[Nouveau] [PATCH v2 6/9] pci: implement PCIe speed change for kepler+

Ben Skeggs skeggsb at gmail.com
Tue Oct 13 15:59:05 PDT 2015


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 10/13/2015 07:44 PM, Karol Herbst wrote:
> v2: rename functions
> 
> Signed-off-by: Karol Herbst <nouveau at karolherbst.de> --- 
> drm/nouveau/nvkm/subdev/pci/gk104.c | 196
> ++++++++++++++++++++++++++++++++++++ 1 file changed, 196
> insertions(+)
> 
> diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c
> b/drm/nouveau/nvkm/subdev/pci/gk104.c index 458dd31..99b131c
> 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++
> b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -23,6 +23,197 @@ */ 
> #include "priv.h"
> 
> +static u32 +gk104_pci2_rd32(struct nvkm_pci *pci, u16 addr) +{ +
> struct nvkm_device *device = pci->subdev.device; +	return
> nvkm_rd32(device, 0x08c000 + addr); +} + +static void 
> +gk104_pci2_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32
> value) +{ +	struct nvkm_device *device = pci->subdev.device; +
> nvkm_mask(device, 0x08c000 + addr, mask, value); +} +
Maybe skip these accessors and use nvkm_rd32/nvkm_mask directly, the
code is very specific to this chipset, and we don't need to abstract
away the mmio aperture difference like we do in some of the other code.

I don't have strong opinions on this one though.

> +static int +gk104_pcie_version_supported(struct nvkm_pci *pci) +{ 
> +	return (gk104_pci2_rd32(pci, 0x1c0) & 0x4) == 0x4 ? 2 : 1; +} + 
> +static void +gk104_pcie_set_cap_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ +	switch (speed) { +	case
> NVKM_PCIE_SPEED_2_5: +		gf100_pcie_set_cap_speed(pci, false); +
> gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x10000); +		break; +	case
> NVKM_PCIE_SPEED_5_0: +		gf100_pcie_set_cap_speed(pci, true); +
> gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x20000); +		break; +	case
> NVKM_PCIE_SPEED_8_0: +		gf100_pcie_set_cap_speed(pci, true); +
> gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x30000); +		break; +	} +} + 
> +static enum nvkm_pcie_speed +gk104_pcie_cap_speed(struct nvkm_pci
> *pci) +{ +	int speed = gf100_pcie_cap_speed(pci); +	if (speed < 0) 
> +		return speed; + +	if (speed == 0) +		return
> NVKM_PCIE_SPEED_2_5; + +	if (speed >= 1) { +		int speed2 =
> gk104_pci2_rd32(pci, 0x1c0) & 0x30000; +		switch (speed2) { +		case
> 0x00000: +		case 0x10000: +			return NVKM_PCIE_SPEED_2_5; +		case
> 0x20000: +			return NVKM_PCIE_SPEED_5_0; +		case 0x30000: +
> return NVKM_PCIE_SPEED_8_0; +		} +	} +	return -EINVAL; +} + +static
> void +gk104_pcie_set_lnkctl_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ +	u8 reg_v = 0; +	switch (speed) { +	case
> NVKM_PCIE_SPEED_2_5: +		reg_v = 1; +		break; +	case
> NVKM_PCIE_SPEED_5_0: +		reg_v = 2; +		break; +	case
> NVKM_PCIE_SPEED_8_0: +		reg_v = 3; +		break; +	} +
> nvkm_pci_mask(pci, 0xa8, 0x3, reg_v); +} + +static enum
> nvkm_pcie_speed +gk104_pcie_lnkctl_speed(struct nvkm_pci *pci) +{ +
> u8 reg_v = nvkm_pci_rd32(pci, 0xa8) & 0x3; +	switch (reg_v) { +
> case 0: +	case 1: +		return NVKM_PCIE_SPEED_2_5; +	case 2: +
> return NVKM_PCIE_SPEED_5_0; +	case 3: +		return
> NVKM_PCIE_SPEED_8_0; +	} +	return -1; +} + +static enum
> nvkm_pcie_speed +gk104_pcie_max_speed(struct nvkm_pci *pci) +{ +
> u32 max_speed = gk104_pci2_rd32(pci, 0x1c0) & 0x300000; +	switch
> (max_speed) { +	case 0x000000: +		return NVKM_PCIE_SPEED_8_0; +
> case 0x100000: +		return NVKM_PCIE_SPEED_5_0; +	case 0x200000: +
> return NVKM_PCIE_SPEED_2_5; +	} +	return NVKM_PCIE_SPEED_2_5; +} + 
> +static void +gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ +	u32 mask_value; +	switch (speed) { +
> default: +	case NVKM_PCIE_SPEED_2_5: +		mask_value = 0x80000; +
> break; +	case NVKM_PCIE_SPEED_5_0: +		mask_value = 0x40000; +
> break; +	case NVKM_PCIE_SPEED_8_0: +		mask_value = 0x00000; +
> break; +	} +	gk104_pci2_mask(pci, 0x40, 0xc0000, mask_value); +
> gk104_pci2_mask(pci, 0x40, 0x1, 0x1); +} + +static int 
> +gk104_pcie_init(struct nvkm_pci * pci) +{ +	if
> (!pci_is_pcie(pci->pdev)) +		return -ENODEV; + +	if
> (gf100_pcie_version(pci) > 1) { +		enum nvkm_pcie_speed +
> lnkctl_speed = gk104_pcie_lnkctl_speed(pci), +			max_speed =
> gk104_pcie_max_speed(pci), +			cap_speed =
> gk104_pcie_cap_speed(pci); + +		if (cap_speed != max_speed) { +
> nvkm_debug(&pci->subdev, "adjusting cap speed to max speed\n"); +
> gk104_pcie_set_cap_speed(pci, max_speed); +			cap_speed =
> gk104_pcie_cap_speed(pci); +			if (cap_speed != max_speed) +
> nvkm_error(&pci->subdev, "couldn't adjust cap speed\n"); +		} + +
> if (lnkctl_speed != max_speed) { +			nvkm_debug(&pci->subdev, +
> "adjusting link control speed to max speed\n"); +
> gk104_pcie_set_lnkctl_speed(pci, max_speed); +			lnkctl_speed =
> gk104_pcie_lnkctl_speed(pci); +			if (lnkctl_speed != max_speed) +
> nvkm_error(&pci->subdev, +					"couldn't adjust link control
> speed\n"); +		} +	} +	return 0; +} + +static int 
> +gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed
> req_speed, +	u8 req_width) +{ +	enum nvkm_pcie_speed +
> lnk_ctl_speed = gk104_pcie_lnkctl_speed(pci), +		lnk_cap_speed =
> gk104_pcie_cap_speed(pci); + +	if (req_speed > lnk_cap_speed) { +
> req_speed = lnk_cap_speed; +		nvkm_warn(&pci->subdev, "dropping
> requested PCIe speed due to low" +				" cap speed\n"); +	} + +	if
> (req_speed > lnk_ctl_speed) { +		req_speed = lnk_ctl_speed; +
> nvkm_warn(&pci->subdev, "dropping requested PCIe speed due to low" 
> +				" control speed\n"); +	} + +	gk104_pcie_set_link_speed(pci,
> req_speed); +	return 0; +} + + static const struct nvkm_pci_func 
> gk104_pci_func = { .rd32 = nv40_pci_rd32, @@ -30,10 +221,15 @@
> gk104_pci_func = { .wr32 = nv40_pci_wr32, .msi_rearm =
> nv40_pci_msi_rearm,
> 
> +	.pcie.init = gk104_pcie_init, +	.pcie.set_link =
> gk104_pcie_set_link, + +	.pcie.max_speed = gk104_pcie_max_speed, 
> .pcie.cur_speed = g84_pcie_cur_speed,
> 
> .pcie.set_version = gf100_pcie_set_version, .pcie.version =
> gf100_pcie_version, +	.pcie.version_supported =
> gk104_pcie_version_supported, };
> 
> int
> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCAAGBQJWHYy5AAoJEHYLnGJQkpH7dTEQAKk+oKbt8nZlrrHEAOjarH6w
sLktjZeqLUUUSyK7KXNrpPgzZtvxmuBqPHTcCyjtJ2l/02d1XPT7d6xaRRxPeoXY
RMeqZoUz2t1yJHHuct6KTncTyYuItfO99G2nDbW5lUR6cW9bMBUnrL/FNbfZ+6VN
AJlFim6wiZ8dKsJalNPBS353dChRabSs6XNXlW1U7tOv52aTHRKt5S/PvEVmdyFW
BMMkYuB/8y47TeqjHZo4l3ZfnhPZ0jaJY76CWLOgSkhAx65bMFcu7px5EM0S2gmG
e4ptteJFq5psaeSiLr3kDa3ry4mDRHpwl/yMa4Ej1neTOt1DOl82GqClD/6QwlOw
QOiE41iPgJJYSPDahhmVnUmGEhuSODBtCOX4pMRo1wtjaPgAeP0hUh+sOZJEag/D
LMjnH5MFCtUcmcUSAUQjMlAZrtZw+Fo3eQglzBFd84Zl9JwdK8dNhKtpe8qWUsaB
Hf0bQhXn/5kZLXkhun+Rjucmi7cH6pTu4fDHSe/cHpzPgf06N8pqFQv+D+HzYRYL
7l+MC/gmzBODTx+hpdC75ETwFWBEQug2wuerpCV+nh4KPMbuLVzsBcF8H8xFwa6d
XDCdEQgk9f7KUT8Q2G3oaRBT6jWv8e7bntzu4kGe35aYBxi6pT6EnsbSFesZjxce
q0HaM0kT14JkA/C+NdHZ
=atdH
-----END PGP SIGNATURE-----


More information about the Nouveau mailing list