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 | } |
