diff options
author | Chaithrika U S <chaithrika@ti.com> | 2009-12-15 16:46:29 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 07:20:02 -0800 |
commit | e04e54835fdaaeebbd95f9508bc814859fcd7afd (patch) | |
tree | 6efecc1a6ecd563ebf47f7070579b71641d949c6 | |
parent | 8097b1749f9265be0f3dbc43c3700da31eb422fd (diff) |
davinci: fb: add cpufreq support
Add cpufreq support for DA8xx/OMAP-L1xx frame buffer driver
Signed-off-by: Chaithrika 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/video/da8xx-fb.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index fe0025213a8..8966274bbbb 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -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); |