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

Commit aee582de authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: run perflvl and M table scripts on mem clock change



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 5c6dc657
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -385,6 +385,8 @@ struct nouveau_pm_level {


	u8 voltage;
	u8 voltage;
	u8 fanspeed;
	u8 fanspeed;

	u16 memscript;
};
};


struct nouveau_pm_temp_sensor_constants {
struct nouveau_pm_temp_sensor_constants {
+1 −0
Original line number Original line Diff line number Diff line
@@ -160,6 +160,7 @@ nouveau_perf_init(struct drm_device *dev)
			perflvl->memory = ROM16(entry[12]) * 1000;
			perflvl->memory = ROM16(entry[12]) * 1000;
			break;
			break;
		case 0x30:
		case 0x30:
			perflvl->memscript = ROM16(entry[2]);
		case 0x35:
		case 0x35:
			perflvl->fanspeed = entry[6];
			perflvl->fanspeed = entry[6];
			perflvl->voltage = entry[7];
			perflvl->voltage = entry[7];
+22 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@


#include "drmP.h"
#include "drmP.h"
#include "nouveau_drv.h"
#include "nouveau_drv.h"
#include "nouveau_bios.h"
#include "nouveau_pm.h"
#include "nouveau_pm.h"


/*XXX: boards using limits 0x40 need fixing, the register layout
/*XXX: boards using limits 0x40 need fixing, the register layout
@@ -33,6 +34,7 @@
 */
 */


struct nv50_pm_state {
struct nv50_pm_state {
	struct nouveau_pm_level *perflvl;
	struct pll_lims pll;
	struct pll_lims pll;
	enum pll_types type;
	enum pll_types type;
	int N, M, P;
	int N, M, P;
@@ -77,6 +79,7 @@ nv50_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
	if (!state)
	if (!state)
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(-ENOMEM);
	state->type = id;
	state->type = id;
	state->perflvl = perflvl;


	ret = get_pll_limits(dev, id, &state->pll);
	ret = get_pll_limits(dev, id, &state->pll);
	if (ret < 0) {
	if (ret < 0) {
@@ -98,11 +101,30 @@ void
nv50_pm_clock_set(struct drm_device *dev, void *pre_state)
nv50_pm_clock_set(struct drm_device *dev, void *pre_state)
{
{
	struct nv50_pm_state *state = pre_state;
	struct nv50_pm_state *state = pre_state;
	struct nouveau_pm_level *perflvl = state->perflvl;
	u32 reg = state->pll.reg, tmp;
	u32 reg = state->pll.reg, tmp;
	struct bit_entry BIT_M;
	u16 script;
	int N = state->N;
	int N = state->N;
	int M = state->M;
	int M = state->M;
	int P = state->P;
	int P = state->P;


	if (state->type == PLL_MEMORY && perflvl->memscript &&
	    bit_table(dev, 'M', &BIT_M) == 0 &&
	    BIT_M.version == 1 && BIT_M.length >= 0x0b) {
		script = ROM16(BIT_M.data[0x05]);
		if (script)
			nouveau_bios_run_init_table(dev, script, NULL);
		script = ROM16(BIT_M.data[0x07]);
		if (script)
			nouveau_bios_run_init_table(dev, script, NULL);
		script = ROM16(BIT_M.data[0x09]);
		if (script)
			nouveau_bios_run_init_table(dev, script, NULL);

		nouveau_bios_run_init_table(dev, perflvl->memscript, NULL);
	}

	if (state->pll.vco2.maxfreq) {
	if (state->pll.vco2.maxfreq) {
		if (state->type == PLL_MEMORY) {
		if (state->type == PLL_MEMORY) {
			nv_wr32(dev, 0x100210, 0);
			nv_wr32(dev, 0x100210, 0);