aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-16 19:03:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-16 19:03:24 -0400
commit498f96204f27f47f1cfdcf498671025125b488d0 (patch)
tree95672ce1ea24527d49036fecd91b11b66f94d7e2
parent5f63517cbf4f8d0d0e27faec6e8b827cbf232b0c (diff)
parentc26ef3eb3c11274bad1b64498d0a134f85755250 (diff)
Merge tag 'fbdev-fixes-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev fixes from Tomi Valkeinen: - fix build errors for bf54x-lq043fb and imxfb - fbcon fix for da8xx-fb - omapdss fixes for hdmi audio, irq handling and fclk calculation * tag 'fbdev-fixes-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: video: bf54x-lq043fb: fix build error OMAPDSS: Change struct reg_field to dispc_reg_field OMAPDSS: Take pixelclock unit change into account in hdmi_compute_acr() OMAPDSS: fix shared irq handlers video: imxfb: Select LCD_CLASS_DEVICE unconditionally OMAPDSS: fix rounding when calculating fclk rate video: da8xx-fb: Fix casting of info->pseudo_palette
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/bf54x-lq043fb.c2
-rw-r--r--drivers/video/da8xx-fb.c10
-rw-r--r--drivers/video/omap2/dss/dispc.c67
-rw-r--r--drivers/video/omap2/dss/dsi.c20
-rw-r--r--drivers/video/omap2/dss/dss.c4
-rw-r--r--drivers/video/omap2/dss/dss.h6
-rw-r--r--drivers/video/omap2/dss/hdmi_common.c8
8 files changed, 87 insertions, 32 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6c793bc683d9..3ad7ebe2a96d 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -359,6 +359,8 @@ config FB_SA1100
359config FB_IMX 359config FB_IMX
360 tristate "Freescale i.MX1/21/25/27 LCD support" 360 tristate "Freescale i.MX1/21/25/27 LCD support"
361 depends on FB && ARCH_MXC 361 depends on FB && ARCH_MXC
362 select BACKLIGHT_LCD_SUPPORT
363 select LCD_CLASS_DEVICE
362 select FB_CFB_FILLRECT 364 select FB_CFB_FILLRECT
363 select FB_CFB_COPYAREA 365 select FB_CFB_COPYAREA
364 select FB_CFB_IMAGEBLIT 366 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 42b8f9d11018..e2c42ad8515a 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -49,13 +49,13 @@
49#include <linux/spinlock.h> 49#include <linux/spinlock.h>
50#include <linux/dma-mapping.h> 50#include <linux/dma-mapping.h>
51#include <linux/platform_device.h> 51#include <linux/platform_device.h>
52#include <linux/gpio.h>
52 53
53#include <asm/blackfin.h> 54#include <asm/blackfin.h>
54#include <asm/irq.h> 55#include <asm/irq.h>
55#include <asm/dpmc.h> 56#include <asm/dpmc.h>
56#include <asm/dma-mapping.h> 57#include <asm/dma-mapping.h>
57#include <asm/dma.h> 58#include <asm/dma.h>
58#include <asm/gpio.h>
59#include <asm/portmux.h> 59#include <asm/portmux.h>
60 60
61#include <mach/bf54x-lq043.h> 61#include <mach/bf54x-lq043.h>
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0c0ba920ea48..6b23508ff0a5 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -663,15 +663,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
663 (green << info->var.green.offset) | 663 (green << info->var.green.offset) |
664 (blue << info->var.blue.offset); 664 (blue << info->var.blue.offset);
665 665
666 switch (info->var.bits_per_pixel) { 666 ((u32 *) (info->pseudo_palette))[regno] = v;
667 case 16:
668 ((u16 *) (info->pseudo_palette))[regno] = v;
669 break;
670 case 24:
671 case 32:
672 ((u32 *) (info->pseudo_palette))[regno] = v;
673 break;
674 }
675 if (palette[0] != 0x4000) { 667 if (palette[0] != 0x4000) {
676 update_hw = 1; 668 update_hw = 1;
677 palette[0] = 0x4000; 669 palette[0] = 0x4000;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 2bbdb7ff7daf..f18397c33e8f 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -101,6 +101,8 @@ static struct {
101 void __iomem *base; 101 void __iomem *base;
102 102
103 int irq; 103 int irq;
104 irq_handler_t user_handler;
105 void *user_data;
104 106
105 unsigned long core_clk_rate; 107 unsigned long core_clk_rate;
106 unsigned long tv_pclk_rate; 108 unsigned long tv_pclk_rate;
@@ -113,6 +115,8 @@ static struct {
113 u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; 115 u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
114 116
115 const struct dispc_features *feat; 117 const struct dispc_features *feat;
118
119 bool is_enabled;
116} dispc; 120} dispc;
117 121
118enum omap_color_component { 122enum omap_color_component {
@@ -141,12 +145,18 @@ enum mgr_reg_fields {
141 DISPC_MGR_FLD_NUM, 145 DISPC_MGR_FLD_NUM,
142}; 146};
143 147
148struct dispc_reg_field {
149 u16 reg;
150 u8 high;
151 u8 low;
152};
153
144static const struct { 154static const struct {
145 const char *name; 155 const char *name;
146 u32 vsync_irq; 156 u32 vsync_irq;
147 u32 framedone_irq; 157 u32 framedone_irq;
148 u32 sync_lost_irq; 158 u32 sync_lost_irq;
149 struct reg_field reg_desc[DISPC_MGR_FLD_NUM]; 159 struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
150} mgr_desc[] = { 160} mgr_desc[] = {
151 [OMAP_DSS_CHANNEL_LCD] = { 161 [OMAP_DSS_CHANNEL_LCD] = {
152 .name = "LCD", 162 .name = "LCD",
@@ -238,13 +248,13 @@ static inline u32 dispc_read_reg(const u16 idx)
238 248
239static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld) 249static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
240{ 250{
241 const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; 251 const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
242 return REG_GET(rfld.reg, rfld.high, rfld.low); 252 return REG_GET(rfld.reg, rfld.high, rfld.low);
243} 253}
244 254
245static void mgr_fld_write(enum omap_channel channel, 255static void mgr_fld_write(enum omap_channel channel,
246 enum mgr_reg_fields regfld, int val) { 256 enum mgr_reg_fields regfld, int val) {
247 const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; 257 const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
248 REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low); 258 REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
249} 259}
250 260
@@ -3669,16 +3679,44 @@ static int __init dispc_init_features(struct platform_device *pdev)
3669 return 0; 3679 return 0;
3670} 3680}
3671 3681
3682static irqreturn_t dispc_irq_handler(int irq, void *arg)
3683{
3684 if (!dispc.is_enabled)
3685 return IRQ_NONE;
3686
3687 return dispc.user_handler(irq, dispc.user_data);
3688}
3689
3672int dispc_request_irq(irq_handler_t handler, void *dev_id) 3690int dispc_request_irq(irq_handler_t handler, void *dev_id)
3673{ 3691{
3674 return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler, 3692 int r;
3675 IRQF_SHARED, "OMAP DISPC", dev_id); 3693
3694 if (dispc.user_handler != NULL)
3695 return -EBUSY;
3696
3697 dispc.user_handler = handler;
3698 dispc.user_data = dev_id;
3699
3700 /* ensure the dispc_irq_handler sees the values above */
3701 smp_wmb();
3702
3703 r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
3704 IRQF_SHARED, "OMAP DISPC", &dispc);
3705 if (r) {
3706 dispc.user_handler = NULL;
3707 dispc.user_data = NULL;
3708 }
3709
3710 return r;
3676} 3711}
3677EXPORT_SYMBOL(dispc_request_irq); 3712EXPORT_SYMBOL(dispc_request_irq);
3678 3713
3679void dispc_free_irq(void *dev_id) 3714void dispc_free_irq(void *dev_id)
3680{ 3715{
3681 devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id); 3716 devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
3717
3718 dispc.user_handler = NULL;
3719 dispc.user_data = NULL;
3682} 3720}
3683EXPORT_SYMBOL(dispc_free_irq); 3721EXPORT_SYMBOL(dispc_free_irq);
3684 3722
@@ -3750,6 +3788,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
3750 3788
3751static int dispc_runtime_suspend(struct device *dev) 3789static int dispc_runtime_suspend(struct device *dev)
3752{ 3790{
3791 dispc.is_enabled = false;
3792 /* ensure the dispc_irq_handler sees the is_enabled value */
3793 smp_wmb();
3794 /* wait for current handler to finish before turning the DISPC off */
3795 synchronize_irq(dispc.irq);
3796
3753 dispc_save_context(); 3797 dispc_save_context();
3754 3798
3755 return 0; 3799 return 0;
@@ -3763,12 +3807,15 @@ static int dispc_runtime_resume(struct device *dev)
3763 * _omap_dispc_initial_config(). We can thus use it to detect if 3807 * _omap_dispc_initial_config(). We can thus use it to detect if
3764 * we have lost register context. 3808 * we have lost register context.
3765 */ 3809 */
3766 if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY) 3810 if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
3767 return 0; 3811 _omap_dispc_initial_config();
3768 3812
3769 _omap_dispc_initial_config(); 3813 dispc_restore_context();
3814 }
3770 3815
3771 dispc_restore_context(); 3816 dispc.is_enabled = true;
3817 /* ensure the dispc_irq_handler sees the is_enabled value */
3818 smp_wmb();
3772 3819
3773 return 0; 3820 return 0;
3774} 3821}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 121d1049d0bc..8be9b04d8849 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -297,6 +297,8 @@ struct dsi_data {
297 297
298 int irq; 298 int irq;
299 299
300 bool is_enabled;
301
300 struct clk *dss_clk; 302 struct clk *dss_clk;
301 struct clk *sys_clk; 303 struct clk *sys_clk;
302 304
@@ -795,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
795 dsidev = (struct platform_device *) arg; 797 dsidev = (struct platform_device *) arg;
796 dsi = dsi_get_dsidrv_data(dsidev); 798 dsi = dsi_get_dsidrv_data(dsidev);
797 799
800 if (!dsi->is_enabled)
801 return IRQ_NONE;
802
798 spin_lock(&dsi->irq_lock); 803 spin_lock(&dsi->irq_lock);
799 804
800 irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); 805 irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
@@ -5671,6 +5676,15 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5671 5676
5672static int dsi_runtime_suspend(struct device *dev) 5677static int dsi_runtime_suspend(struct device *dev)
5673{ 5678{
5679 struct platform_device *pdev = to_platform_device(dev);
5680 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5681
5682 dsi->is_enabled = false;
5683 /* ensure the irq handler sees the is_enabled value */
5684 smp_wmb();
5685 /* wait for current handler to finish before turning the DSI off */
5686 synchronize_irq(dsi->irq);
5687
5674 dispc_runtime_put(); 5688 dispc_runtime_put();
5675 5689
5676 return 0; 5690 return 0;
@@ -5678,12 +5692,18 @@ static int dsi_runtime_suspend(struct device *dev)
5678 5692
5679static int dsi_runtime_resume(struct device *dev) 5693static int dsi_runtime_resume(struct device *dev)
5680{ 5694{
5695 struct platform_device *pdev = to_platform_device(dev);
5696 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5681 int r; 5697 int r;
5682 5698
5683 r = dispc_runtime_get(); 5699 r = dispc_runtime_get();
5684 if (r) 5700 if (r)
5685 return r; 5701 return r;
5686 5702
5703 dsi->is_enabled = true;
5704 /* ensure the irq handler sees the is_enabled value */
5705 smp_wmb();
5706
5687 return 0; 5707 return 0;
5688} 5708}
5689 5709
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 825c019ddee7..d55266c0e029 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -457,7 +457,7 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
457 fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul); 457 fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
458 458
459 for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { 459 for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
460 fck = prate / fckd * m; 460 fck = DIV_ROUND_UP(prate, fckd) * m;
461 461
462 if (func(fck, data)) 462 if (func(fck, data))
463 return true; 463 return true;
@@ -506,7 +506,7 @@ static int dss_setup_default_clock(void)
506 506
507 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, 507 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
508 max_dss_fck); 508 max_dss_fck);
509 fck = prate / fck_div * dss.feat->dss_fck_multiplier; 509 fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
510 } 510 }
511 511
512 r = dss_set_fck_rate(fck); 512 r = dss_set_fck_rate(fck);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 918fec182424..560078fcb198 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -131,12 +131,6 @@ struct dsi_clock_info {
131 u16 lp_clk_div; 131 u16 lp_clk_div;
132}; 132};
133 133
134struct reg_field {
135 u16 reg;
136 u8 high;
137 u8 low;
138};
139
140struct dss_lcd_mgr_config { 134struct dss_lcd_mgr_config {
141 enum dss_io_pad_mode io_pad_mode; 135 enum dss_io_pad_mode io_pad_mode;
142 136
diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/omap2/dss/hdmi_common.c
index b11afac8e068..0b12a3f62fe1 100644
--- a/drivers/video/omap2/dss/hdmi_common.c
+++ b/drivers/video/omap2/dss/hdmi_common.c
@@ -347,17 +347,17 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
347 case 96000: 347 case 96000:
348 case 192000: 348 case 192000:
349 if (deep_color == 125) 349 if (deep_color == 125)
350 if (pclk == 27027 || pclk == 74250) 350 if (pclk == 27027000 || pclk == 74250000)
351 deep_color_correct = true; 351 deep_color_correct = true;
352 if (deep_color == 150) 352 if (deep_color == 150)
353 if (pclk == 27027) 353 if (pclk == 27027000)
354 deep_color_correct = true; 354 deep_color_correct = true;
355 break; 355 break;
356 case 44100: 356 case 44100:
357 case 88200: 357 case 88200:
358 case 176400: 358 case 176400:
359 if (deep_color == 125) 359 if (deep_color == 125)
360 if (pclk == 27027) 360 if (pclk == 27027000)
361 deep_color_correct = true; 361 deep_color_correct = true;
362 break; 362 break;
363 default: 363 default:
@@ -418,7 +418,7 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
418 } 418 }
419 } 419 }
420 /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ 420 /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
421 *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); 421 *cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);
422 422
423 return 0; 423 return 0;
424} 424}