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

Commit e04e5483 authored by Chaithrika U S's avatar Chaithrika U S Committed by Linus Torvalds
Browse files

davinci: fb: add cpufreq support



Add cpufreq support for DA8xx/OMAP-L1xx frame buffer driver

Signed-off-by: default avatarChaithrika U S <chaithrika@ti.com>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8097b174
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <video/da8xx-fb.h>

#define DRIVER_NAME "da8xx_lcdc"
@@ -114,6 +115,9 @@ struct da8xx_fb_par {
	unsigned int databuf_sz;
	unsigned int palette_sz;
	unsigned int pxl_clk;
#ifdef CONFIG_CPU_FREQ
	struct notifier_block	freq_transition;
#endif
};

/* Variable Screen Information */
@@ -586,6 +590,41 @@ static int fb_check_var(struct fb_var_screeninfo *var,
	return err;
}

#ifdef CONFIG_CPU_FREQ
static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
				     unsigned long val, void *data)
{
	struct da8xx_fb_par *par;
	unsigned int reg;

	par = container_of(nb, struct da8xx_fb_par, freq_transition);
	if (val == CPUFREQ_PRECHANGE) {
		reg = lcdc_read(LCD_RASTER_CTRL_REG);
		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
	} else if (val == CPUFREQ_POSTCHANGE) {
		lcd_calc_clk_divider(par);
		reg = lcdc_read(LCD_RASTER_CTRL_REG);
		lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
	}

	return 0;
}

static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par)
{
	par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition;

	return cpufreq_register_notifier(&par->freq_transition,
					 CPUFREQ_TRANSITION_NOTIFIER);
}

static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
{
	cpufreq_unregister_notifier(&par->freq_transition,
				    CPUFREQ_TRANSITION_NOTIFIER);
}
#endif

static int __devexit fb_remove(struct platform_device *dev)
{
	struct fb_info *info = dev_get_drvdata(&dev->dev);
@@ -593,6 +632,9 @@ static int __devexit fb_remove(struct platform_device *dev)
	if (info) {
		struct da8xx_fb_par *par = info->par;

#ifdef CONFIG_CPU_FREQ
		lcd_da8xx_cpufreq_deregister(par);
#endif
		if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE)
			lcd_disable_raster(par);
		lcdc_write(0, LCD_RASTER_CTRL_REG);
@@ -826,12 +868,25 @@ static int __init fb_probe(struct platform_device *device)
		goto err_dealloc_cmap;
	}

#ifdef CONFIG_CPU_FREQ
	ret = lcd_da8xx_cpufreq_register(par);
	if (ret) {
		dev_err(&device->dev, "failed to register cpufreq\n");
		goto err_cpu_freq;
	}
#endif

	/* enable raster engine */
	lcdc_write(lcdc_read(LCD_RASTER_CTRL_REG) |
			LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);

	return 0;

#ifdef CONFIG_CPU_FREQ
err_cpu_freq:
	unregister_framebuffer(da8xx_fb_info);
#endif

err_dealloc_cmap:
	fb_dealloc_cmap(&da8xx_fb_info->cmap);