All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tobias Klausmann <tobias.johannes.klausmann-AqjdNwhu20eELgA04lAiVw@public.gmane.org>
To: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers
Date: Sat, 23 May 2015 01:00:17 +0200	[thread overview]
Message-ID: <555FB501.4010206@mni.thm.de> (raw)
In-Reply-To: <1432334028-15234-5-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>



On 23.05.2015 00:33, Roy Spliet wrote:
> Might need some generalisation to < GT200. For those: use at your own risk!
>
> Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
> ---
>   .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  16 ++
>   .../drm/nouveau/include/nvkm/subdev/bios/rammap.h  |   2 +
>   drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  29 ++++
>   drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c   | 167 +++++++++++++++++----
>   4 files changed, 181 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> index c6fb6aa..f09b6bf 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> @@ -35,6 +35,22 @@ struct nvbios_ramcfg {
>   	unsigned ramcfg_DLLoff;
>   	union {
>   		struct {
> +			unsigned ramcfg_00_03_01:1;
> +			unsigned ramcfg_00_03_02:1;
> +			unsigned ramcfg_00_03_08:1;
> +			unsigned ramcfg_00_03_10:1;
> +			unsigned ramcfg_00_04_02:1;
> +			unsigned ramcfg_00_04_04:1;
> +			unsigned ramcfg_00_04_20:1;
> +			unsigned ramcfg_00_05:8;
> +			unsigned ramcfg_00_06:8;
> +			unsigned ramcfg_00_07:8;
> +			unsigned ramcfg_00_08:8;
> +			unsigned ramcfg_00_09:8;
> +			unsigned ramcfg_00_0a_0f:4;
> +			unsigned ramcfg_00_0a_f0:4;
> +		};
> +		struct {
>   			unsigned ramcfg_10_02_01:1;
>   			unsigned ramcfg_10_02_02:1;
>   			unsigned ramcfg_10_02_04:1;
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
> index 609a905..2044fc9 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
> @@ -15,6 +15,8 @@ u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
>   u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
>   		    u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
>   		    u8 *ver, u8 *hdr);
> +u32 nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
> +		    struct nvbios_ramcfg *p);
>   u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
>   		    u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
>   		    u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
> index a688d3b..4ec376a 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
> @@ -141,6 +141,35 @@ nvbios_rammapSe(struct nvkm_bios *bios, u32 data,
>   }
>   
>   u32
> +nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
> +		struct nvbios_ramcfg *p)
> +{
> +	data += (idx * size);
> +
> +	if (size < 11)
> +		return NULL;
> +
> +	p->ramcfg_timing   =  nv_ro08(bios, data + 0x01);
> +	p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
> +	p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
> +	p->ramcfg_DLLoff   = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
> +	p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
> +	p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
> +	p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
> +	p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
> +	p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
> +	p->ramcfg_00_05    = (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
> +	p->ramcfg_00_06    = (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
> +	p->ramcfg_00_07    = (nv_ro08(bios, data + 0x07) & 0xff) >> 0;
> +	p->ramcfg_00_08    = (nv_ro08(bios, data + 0x08) & 0xff) >> 0;
> +	p->ramcfg_00_09    = (nv_ro08(bios, data + 0x09) & 0xff) >> 0;
> +	p->ramcfg_00_0a_0f = (nv_ro08(bios, data + 0x0a) & 0x0f) >> 0;
> +	p->ramcfg_00_0a_f0 = (nv_ro08(bios, data + 0x0a) & 0xf0) >> 4;
> +
> +	return data;
> +}
> +
> +u32
>   nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
>   		u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
>   		u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> index a96e512..51f93a0 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> @@ -29,6 +29,7 @@
>   #include <subdev/bios.h>
>   #include <subdev/bios/perf.h>
>   #include <subdev/bios/pll.h>
> +#include <subdev/bios/rammap.h>
>   #include <subdev/bios/timing.h>
>   #include <subdev/clk/pll.h>
>   
> @@ -55,6 +56,84 @@ struct nv50_ram {
>   	struct nv50_ramseq hwsq;
>   };
>   
> +#define T(t) cfg->timing_10_##t
> +static int
> +nv50_ram_timing_calc(struct nvkm_fb *pfb, u32 *timing)
> +{
> +	struct nv50_ram *ram = (void *)pfb->ram;
> +	struct nvbios_ramcfg *cfg = &ram->base.target.bios;
> +	u32 cur2, cur3, cur4, cur7, cur8;
> +	u8 unkt3b;
> +
> +	cur2 = nv_rd32(pfb, 0x100228);
> +	cur3 = nv_rd32(pfb, 0x10022c);
> +	cur4 = nv_rd32(pfb, 0x100230);
> +	cur7 = nv_rd32(pfb, 0x10023c);
> +	cur8 = nv_rd32(pfb, 0x100240);
> +
> +	switch ((!T(CWL)) * ram->base.type) {
> +	case NV_MEM_TYPE_DDR2:
> +		T(CWL) = T(CL) - 1;
> +		break;
> +	case NV_MEM_TYPE_GDDR3:
> +		T(CWL) = ((cur2 & 0xff000000) >> 24) + 1;
> +		break;
> +	}
> +
> +	/* XXX: N=1 is not proper statistics */
> +	if (nv_device(pfb)->chipset == 0xa0) {
> +		unkt3b = 0x19 + ram->base.next->bios.rammap_00_16_40;
> +		timing[6] = (0x2d + T(CL) - T(CWL) + ram->base.next->bios.rammap_00_16_40) << 16 |
> +			    T(CWL) << 8 |
> +			    (0x2f + T(CL) - T(CWL));
> +	} else {
> +		unkt3b = 0x16;
> +		timing[6] = (0x2b + T(CL) - T(CWL)) << 16 |
> +			    max_t(s8, T(CWL) - 2, 1) << 8 |
> +			    (0x2e + T(CL) - T(CWL));
> +	}
> +
> +	timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) << 8 | T(RC));
> +	timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
> +		    max_t(u8, T(18), 1) << 16 |
> +		    (T(WTR) + 1 + T(CWL)) << 8 |
> +		    (3 + T(CL) - T(CWL));
> +	timing[2] = (T(CWL) - 1) << 24 |
> +		    (T(RRD) << 16) |
> +		    (T(RCDWR) << 8) |
> +		    T(RCDRD);
> +	timing[3] = (unkt3b - 2 + T(CL)) << 24 |
> +		    unkt3b << 16 |
> +		    (T(CL) - 1) << 8 |
> +		    (T(CL) - 1);
> +	timing[4] = (cur4 & 0xffff0000) |
> +		    T(13) << 8 |
> +		    T(13);
> +	timing[5] = T(RFC) << 24 |
> +		    max_t(u8, T(RCDRD), T(RCDWR)) << 16 |
> +		    T(RP);
> +	/* Timing 6 is already done above */
> +	timing[7] = (cur7 & 0xff00ffff) | (T(CL) - 1) << 16;
> +	timing[8] = (cur8 & 0xffffff00);
> +
> +	/* XXX: P.version == 1 only has DDR2 and GDDR3? */

mh can you state both (DDR2/GDDR3) here and bail out on default as well?

> +	if (pfb->ram->type == NV_MEM_TYPE_DDR2) {
> +		timing[5] |= (T(CL) + 3) << 8;
> +		timing[8] |= (T(CL) - 4);
> +	} else {
> +		timing[5] |= (T(CL) + 2) << 8;
> +		timing[8] |= (T(CL) - 2);
> +	}
> +
> +	nv_debug(pfb, " 220: %08x %08x %08x %08x\n",
> +			timing[0], timing[1], timing[2], timing[3]);
> +	nv_debug(pfb, " 230: %08x %08x %08x %08x\n",
> +			timing[4], timing[5], timing[6], timing[7]);
> +	nv_debug(pfb, " 240: %08x\n", timing[8]);
> +	return 0;
> +}
> +#undef T
> +
>   #define QFX5800NVA0 1
>   
>   static int
> @@ -65,22 +144,25 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
>   	struct nv50_ramseq *hwsq = &ram->hwsq;
>   	struct nvbios_perfE perfE;
>   	struct nvbios_pll mpll;
> -	struct {
> -		u32 data;
> -		u8  size;
> -	} ramcfg, timing;
> -	u8  ver, hdr, cnt, len, strap;
> +	struct nvkm_ram_data *next;
> +	u8  ver, hdr, cnt, len, strap, size;
> +	u32 data;
>   	u32 r100da0;
>   	int N1, M1, N2, M2, P;
>   	int ret, i;
> +	u32 timing[9];
> +
> +	next = &ram->base.target;
> +	next->freq = freq;
> +	ram->base.next = next;
>   
>   	/* lookup closest matching performance table entry for frequency */
>   	i = 0;
>   	do {
> -		ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
> -					    &ramcfg.size, &perfE);
> -		if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) ||
> -		    (ramcfg.size < 2)) {
> +		data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
> +					    &size, &perfE);
> +		if (!data || (ver < 0x25 || ver >= 0x40) ||
> +		    (size < 2)) {
>   			nv_error(pfb, "invalid/missing perftab entry\n");
>   			return -EINVAL;
>   		}
> @@ -93,23 +175,48 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
>   		return -EINVAL;
>   	}
>   
> -	ramcfg.data += hdr + (strap * ramcfg.size);
> +	data = nvbios_rammapSp_from_perf(bios, data + hdr, size, strap,
> +			&next->bios);
> +	if (!data) {
> +		nv_error(pfb, "invalid/missing rammap entry ");
> +		return -EINVAL;
> +	}
>   
>   	/* lookup memory timings, if bios says they're present */
> -	strap = nv_ro08(bios, ramcfg.data + 0x01);
> -	if (strap != 0xff) {
> -		timing.data = nvbios_timingEe(bios, strap, &ver, &hdr,
> -					      &cnt, &len);
> -		if (!timing.data || ver != 0x10 || hdr < 0x12) {
> +	if (next->bios.ramcfg_timing != 0xff) {
> +		data = nvbios_timingEp(bios, next->bios.ramcfg_timing,
> +					&ver, &hdr, &cnt, &len, &next->bios);
> +		if (!data || ver != 0x10 || hdr < 0x12) {
>   			nv_error(pfb, "invalid/missing timing entry "
>   				 "%02x %04x %02x %02x\n",
> -				 strap, timing.data, ver, hdr);
> +				 strap, data, ver, hdr);
>   			return -EINVAL;
>   		}
> -	} else {
> -		timing.data = 0;
>   	}
>   
> +	nv50_ram_timing_calc(pfb, timing);
> +
> +	ret = ram_init(hwsq, nv_subdev(pfb));
> +	if (ret)
> +		return ret;
> +
> +	/* Determine ram-specific MR values */
> +	ram->base.mr[0] = ram_rd32(hwsq, mr[0]);
> +	ram->base.mr[1] = ram_rd32(hwsq, mr[1]);
> +	ram->base.mr[2] = ram_rd32(hwsq, mr[2]);
> +
> +	switch (ram->base.type) {
> +	case NV_MEM_TYPE_GDDR3:
> +		ret = nvkm_gddr3_calc(&ram->base);
> +		break;
> +	default:
> +		ret = -ENOSYS;
> +		break;
> +	}
> +
> +	if (ret)
> +		return ret;
> +
>   	/* XXX: where the fuck does 750MHz come from? */

get rid of that swearing...

>   	if (freq <= 750000) {
>   		r100da0 = 0x00000010;
> @@ -117,10 +224,6 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
>   		r100da0 = 0x00000000;
>   	}
>   
> -	ret = ram_init(hwsq, nv_subdev(pfb));
> -	if (ret)
> -		return ret;
> -
>   	ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
>   	ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
>   	ram_wr32(hwsq, 0x611200, 0x00003300);
> @@ -177,17 +280,15 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
>   		break;
>   	}
>   
> -	ram_mask(hwsq, timing[3], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[1], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[6], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[7], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[8], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[2], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[4], 0x00000000, 0x00000000); /*XXX*/
> -	ram_mask(hwsq, timing[5], 0x00000000, 0x00000000); /*XXX*/
> -
> -	ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
> +	ram_mask(hwsq, timing[3], 0xffffffff, timing[3]);
> +	ram_mask(hwsq, timing[1], 0xffffffff, timing[1]);
> +	ram_mask(hwsq, timing[6], 0xffffffff, timing[6]);
> +	ram_mask(hwsq, timing[7], 0xffffffff, timing[7]);
> +	ram_mask(hwsq, timing[8], 0xffffffff, timing[8]);
> +	ram_mask(hwsq, timing[0], 0xffffffff, timing[0]);
> +	ram_mask(hwsq, timing[2], 0xffffffff, timing[2]);
> +	ram_mask(hwsq, timing[4], 0xffffffff, timing[4]);
> +	ram_mask(hwsq, timing[5], 0xffffffff, timing[5]);
>   
>   #if QFX5800NVA0
>   	ram_nuke(hwsq, 0x100e24);

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

  parent reply	other threads:[~2015-05-22 23:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-22 22:33 Reclocking support for NVA0 Roy Spliet
     [not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:33   ` [PATCH 1/9] nvkm/clk/gt215: u32->s32 for difference in req. and set clock Roy Spliet
2015-05-22 22:33   ` [PATCH 2/9] nvkm/bios/rammap: Pull DLLoff bit out of version 0x10 struct Roy Spliet
2015-05-22 22:33   ` [PATCH 3/9] nvkm/fb/ramnv50: Make 0x100da0 per-partition Roy Spliet
     [not found]     ` <1432334028-15234-4-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:44       ` Ilia Mirkin
2015-05-22 22:33   ` [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers Roy Spliet
     [not found]     ` <1432334028-15234-5-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 23:00       ` Tobias Klausmann [this message]
     [not found]         ` <555FB501.4010206-AqjdNwhu20eELgA04lAiVw@public.gmane.org>
2015-05-23  8:35           ` Roy Spliet
2015-05-22 22:33   ` [PATCH 5/9] nvkm/bios/rammap: Parse perf mode as if it's a rammap entry Roy Spliet
2015-05-22 22:33   ` [PATCH 6/9] nvkm/bios/ramcfg: Separate out RON pull value Roy Spliet
2015-05-22 22:33   ` [PATCH 7/9] nvkm/fb/ramnv50: GDDR3 script for NVA0 Roy Spliet
2015-05-22 22:33   ` [PATCH 8/9] nvkm/fb/gddr3: Add a few CL and WR entries observed on GTX260 Roy Spliet
2015-05-22 22:33   ` [PATCH 9/9] nvkm/clk/nv50: Enable user reclocking for NVA0 Roy Spliet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=555FB501.4010206@mni.thm.de \
    --to=tobias.johannes.klausmann-aqjdnwhu20eelga04laivw@public.gmane.org \
    --cc=nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.