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

Commit 36f1317e authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv04-nv30/pm: port to newer interfaces



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f3fbaf34
Loading
Loading
Loading
Loading
+3 −4
Original line number Original line Diff line number Diff line
@@ -47,10 +47,9 @@ void nouveau_mem_timing_init(struct drm_device *);
void nouveau_mem_timing_fini(struct drm_device *);
void nouveau_mem_timing_fini(struct drm_device *);


/* nv04_pm.c */
/* nv04_pm.c */
int nv04_pm_clock_get(struct drm_device *, u32 id);
int nv04_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
void *nv04_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
void *nv04_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
			u32 id, int khz);
int nv04_pm_clocks_set(struct drm_device *, void *);
void nv04_pm_clock_set(struct drm_device *, void *);


/* nv40_pm.c */
/* nv40_pm.c */
int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
+12 −12
Original line number Original line Diff line number Diff line
@@ -87,9 +87,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->gpio.get		= NULL;
		engine->gpio.get		= NULL;
		engine->gpio.set		= NULL;
		engine->gpio.set		= NULL;
		engine->gpio.irq_enable		= NULL;
		engine->gpio.irq_enable		= NULL;
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.takedown		= nouveau_stub_takedown;
		engine->vram.takedown		= nouveau_stub_takedown;
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
@@ -136,9 +136,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		engine->gpio.irq_enable		= NULL;
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.takedown		= nouveau_stub_takedown;
		engine->vram.takedown		= nouveau_stub_takedown;
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
@@ -185,9 +185,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		engine->gpio.irq_enable		= NULL;
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.takedown		= nouveau_stub_takedown;
		engine->vram.takedown		= nouveau_stub_takedown;
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
@@ -234,9 +234,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		engine->gpio.irq_enable		= NULL;
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
		engine->vram.init		= nouveau_mem_detect;
		engine->vram.init		= nouveau_mem_detect;
+76 −33
Original line number Original line Diff line number Diff line
@@ -27,68 +27,111 @@
#include "nouveau_hw.h"
#include "nouveau_hw.h"
#include "nouveau_pm.h"
#include "nouveau_pm.h"


struct nv04_pm_state {
int
nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
	int ret;

	ret = nouveau_hw_get_clock(dev, PLL_CORE);
	if (ret < 0)
		return ret;
	perflvl->core = ret;

	ret = nouveau_hw_get_clock(dev, PLL_MEMORY);
	if (ret < 0)
		return ret;
	perflvl->memory = ret;

	return 0;
}

struct nv04_pm_clock {
	struct pll_lims pll;
	struct pll_lims pll;
	struct nouveau_pll_vals calc;
	struct nouveau_pll_vals calc;
};
};


int
struct nv04_pm_state {
nv04_pm_clock_get(struct drm_device *dev, u32 id)
	struct nv04_pm_clock core;
	struct nv04_pm_clock memory;
};

static int
calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk)
{
{
	return nouveau_hw_get_clock(dev, id);
	int ret;

	ret = get_pll_limits(dev, id, &clk->pll);
	if (ret)
		return ret;

	ret = nouveau_calc_pll_mnp(dev, &clk->pll, khz, &clk->calc);
	if (!ret)
		return -EINVAL;

	return 0;
}
}


void *
void *
nv04_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
nv04_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
		  u32 id, int khz)
{
{
	struct nv04_pm_state *state;
	struct nv04_pm_state *info;
	int ret;
	int ret;


	state = kzalloc(sizeof(*state), GFP_KERNEL);
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!state)
	if (!info)
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(-ENOMEM);


	ret = get_pll_limits(dev, id, &state->pll);
	ret = calc_pll(dev, PLL_CORE, perflvl->core, &info->core);
	if (ret) {
	if (ret)
		kfree(state);
		goto error;
		return (ret == -ENOENT) ? NULL : ERR_PTR(ret);
	}


	ret = nouveau_calc_pll_mnp(dev, &state->pll, khz, &state->calc);
	if (perflvl->memory) {
	if (!ret) {
		ret = calc_pll(dev, PLL_MEMORY, perflvl->memory, &info->memory);
		kfree(state);
		if (ret)
		return ERR_PTR(-EINVAL);
			goto error;
	}
	}


	return state;
	return info;
error:
	kfree(info);
	return ERR_PTR(ret);
}
}


void
static void
nv04_pm_clock_set(struct drm_device *dev, void *pre_state)
prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk)
{
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
	u32 reg = clk->pll.reg;
	struct nv04_pm_state *state = pre_state;
	u32 reg = state->pll.reg;


	/* thank the insane nouveau_hw_setpll() interface for this */
	/* thank the insane nouveau_hw_setpll() interface for this */
	if (dev_priv->card_type >= NV_40)
	if (dev_priv->card_type >= NV_40)
		reg += 4;
		reg += 4;


	nouveau_hw_setpll(dev, reg, &state->calc);
	nouveau_hw_setpll(dev, reg, &clk->calc);
}

int
nv04_pm_clocks_set(struct drm_device *dev, void *pre_state)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
	struct nv04_pm_state *state = pre_state;

	prog_pll(dev, &state->core);


	if (dev_priv->card_type < NV_30 && reg == NV_PRAMDAC_MPLL_COEFF) {
	if (state->memory.pll.reg) {
		prog_pll(dev, &state->memory);
		if (dev_priv->card_type < NV_30) {
			if (dev_priv->card_type == NV_20)
			if (dev_priv->card_type == NV_20)
				nv_mask(dev, 0x1002c4, 0, 1 << 20);
				nv_mask(dev, 0x1002c4, 0, 1 << 20);


			/* Reset the DLLs */
			/* Reset the DLLs */
			nv_mask(dev, 0x1002c0, 0, 1 << 8);
			nv_mask(dev, 0x1002c0, 0, 1 << 8);
		}
		}
	}


	if (reg == NV_PRAMDAC_NVPLL_COEFF)
	ptimer->init(dev);
	ptimer->init(dev);


	kfree(state);
	kfree(state);
	return 0;
}
}