diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-16 19:03:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-16 19:03:24 -0400 |
commit | 498f96204f27f47f1cfdcf498671025125b488d0 (patch) | |
tree | 95672ce1ea24527d49036fecd91b11b66f94d7e2 | |
parent | 5f63517cbf4f8d0d0e27faec6e8b827cbf232b0c (diff) | |
parent | c26ef3eb3c11274bad1b64498d0a134f85755250 (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/Kconfig | 2 | ||||
-rw-r--r-- | drivers/video/bf54x-lq043fb.c | 2 | ||||
-rw-r--r-- | drivers/video/da8xx-fb.c | 10 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 67 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 20 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 4 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 6 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi_common.c | 8 |
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 | |||
359 | config FB_IMX | 359 | config 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 | ||
118 | enum omap_color_component { | 122 | enum 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 | ||
148 | struct dispc_reg_field { | ||
149 | u16 reg; | ||
150 | u8 high; | ||
151 | u8 low; | ||
152 | }; | ||
153 | |||
144 | static const struct { | 154 | static 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 | ||
239 | static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld) | 249 | static 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 | ||
245 | static void mgr_fld_write(enum omap_channel channel, | 255 | static 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 | ||
3682 | static 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 | |||
3672 | int dispc_request_irq(irq_handler_t handler, void *dev_id) | 3690 | int 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 | } |
3677 | EXPORT_SYMBOL(dispc_request_irq); | 3712 | EXPORT_SYMBOL(dispc_request_irq); |
3678 | 3713 | ||
3679 | void dispc_free_irq(void *dev_id) | 3714 | void 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 | } |
3683 | EXPORT_SYMBOL(dispc_free_irq); | 3721 | EXPORT_SYMBOL(dispc_free_irq); |
3684 | 3722 | ||
@@ -3750,6 +3788,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev) | |||
3750 | 3788 | ||
3751 | static int dispc_runtime_suspend(struct device *dev) | 3789 | static 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 | ||
5672 | static int dsi_runtime_suspend(struct device *dev) | 5677 | static 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 | ||
5679 | static int dsi_runtime_resume(struct device *dev) | 5693 | static 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 | ||
134 | struct reg_field { | ||
135 | u16 reg; | ||
136 | u8 high; | ||
137 | u8 low; | ||
138 | }; | ||
139 | |||
140 | struct dss_lcd_mgr_config { | 134 | struct 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 | } |