Skip to content

Commit

Permalink
Merge tag 'fbdev-fixes-3.15' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/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
  • Loading branch information
Linus Torvalds committed Apr 16, 2014
2 parents 5f63517 + c26ef3e commit 498f962
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 32 deletions.
2 changes: 2 additions & 0 deletions drivers/video/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ config FB_SA1100
config FB_IMX
tristate "Freescale i.MX1/21/25/27 LCD support"
depends on FB && ARCH_MXC
select BACKLIGHT_LCD_SUPPORT
select LCD_CLASS_DEVICE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
Expand Down
2 changes: 1 addition & 1 deletion drivers/video/bf54x-lq043fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>

#include <asm/blackfin.h>
#include <asm/irq.h>
#include <asm/dpmc.h>
#include <asm/dma-mapping.h>
#include <asm/dma.h>
#include <asm/gpio.h>
#include <asm/portmux.h>

#include <mach/bf54x-lq043.h>
Expand Down
10 changes: 1 addition & 9 deletions drivers/video/da8xx-fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,15 +663,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
(green << info->var.green.offset) |
(blue << info->var.blue.offset);

switch (info->var.bits_per_pixel) {
case 16:
((u16 *) (info->pseudo_palette))[regno] = v;
break;
case 24:
case 32:
((u32 *) (info->pseudo_palette))[regno] = v;
break;
}
((u32 *) (info->pseudo_palette))[regno] = v;
if (palette[0] != 0x4000) {
update_hw = 1;
palette[0] = 0x4000;
Expand Down
67 changes: 57 additions & 10 deletions drivers/video/omap2/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ static struct {
void __iomem *base;

int irq;
irq_handler_t user_handler;
void *user_data;

unsigned long core_clk_rate;
unsigned long tv_pclk_rate;
Expand All @@ -113,6 +115,8 @@ static struct {
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];

const struct dispc_features *feat;

bool is_enabled;
} dispc;

enum omap_color_component {
Expand Down Expand Up @@ -141,12 +145,18 @@ enum mgr_reg_fields {
DISPC_MGR_FLD_NUM,
};

struct dispc_reg_field {
u16 reg;
u8 high;
u8 low;
};

static const struct {
const char *name;
u32 vsync_irq;
u32 framedone_irq;
u32 sync_lost_irq;
struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
} mgr_desc[] = {
[OMAP_DSS_CHANNEL_LCD] = {
.name = "LCD",
Expand Down Expand Up @@ -238,13 +248,13 @@ static inline u32 dispc_read_reg(const u16 idx)

static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
{
const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
return REG_GET(rfld.reg, rfld.high, rfld.low);
}

static void mgr_fld_write(enum omap_channel channel,
enum mgr_reg_fields regfld, int val) {
const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
}

Expand Down Expand Up @@ -3669,16 +3679,44 @@ static int __init dispc_init_features(struct platform_device *pdev)
return 0;
}

static irqreturn_t dispc_irq_handler(int irq, void *arg)
{
if (!dispc.is_enabled)
return IRQ_NONE;

return dispc.user_handler(irq, dispc.user_data);
}

int dispc_request_irq(irq_handler_t handler, void *dev_id)
{
return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
IRQF_SHARED, "OMAP DISPC", dev_id);
int r;

if (dispc.user_handler != NULL)
return -EBUSY;

dispc.user_handler = handler;
dispc.user_data = dev_id;

/* ensure the dispc_irq_handler sees the values above */
smp_wmb();

r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
IRQF_SHARED, "OMAP DISPC", &dispc);
if (r) {
dispc.user_handler = NULL;
dispc.user_data = NULL;
}

return r;
}
EXPORT_SYMBOL(dispc_request_irq);

void dispc_free_irq(void *dev_id)
{
devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);

dispc.user_handler = NULL;
dispc.user_data = NULL;
}
EXPORT_SYMBOL(dispc_free_irq);

Expand Down Expand Up @@ -3750,6 +3788,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)

static int dispc_runtime_suspend(struct device *dev)
{
dispc.is_enabled = false;
/* ensure the dispc_irq_handler sees the is_enabled value */
smp_wmb();
/* wait for current handler to finish before turning the DISPC off */
synchronize_irq(dispc.irq);

dispc_save_context();

return 0;
Expand All @@ -3763,12 +3807,15 @@ static int dispc_runtime_resume(struct device *dev)
* _omap_dispc_initial_config(). We can thus use it to detect if
* we have lost register context.
*/
if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
return 0;
if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
_omap_dispc_initial_config();

_omap_dispc_initial_config();
dispc_restore_context();
}

dispc_restore_context();
dispc.is_enabled = true;
/* ensure the dispc_irq_handler sees the is_enabled value */
smp_wmb();

return 0;
}
Expand Down
20 changes: 20 additions & 0 deletions drivers/video/omap2/dss/dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ struct dsi_data {

int irq;

bool is_enabled;

struct clk *dss_clk;
struct clk *sys_clk;

Expand Down Expand Up @@ -795,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
dsidev = (struct platform_device *) arg;
dsi = dsi_get_dsidrv_data(dsidev);

if (!dsi->is_enabled)
return IRQ_NONE;

spin_lock(&dsi->irq_lock);

irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
Expand Down Expand Up @@ -5671,19 +5676,34 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)

static int dsi_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);

dsi->is_enabled = false;
/* ensure the irq handler sees the is_enabled value */
smp_wmb();
/* wait for current handler to finish before turning the DSI off */
synchronize_irq(dsi->irq);

dispc_runtime_put();

return 0;
}

static int dsi_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
int r;

r = dispc_runtime_get();
if (r)
return r;

dsi->is_enabled = true;
/* ensure the irq handler sees the is_enabled value */
smp_wmb();

return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/video/omap2/dss/dss.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);

for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
fck = prate / fckd * m;
fck = DIV_ROUND_UP(prate, fckd) * m;

if (func(fck, data))
return true;
Expand Down Expand Up @@ -506,7 +506,7 @@ static int dss_setup_default_clock(void)

fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
max_dss_fck);
fck = prate / fck_div * dss.feat->dss_fck_multiplier;
fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
}

r = dss_set_fck_rate(fck);
Expand Down
6 changes: 0 additions & 6 deletions drivers/video/omap2/dss/dss.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,6 @@ struct dsi_clock_info {
u16 lp_clk_div;
};

struct reg_field {
u16 reg;
u8 high;
u8 low;
};

struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode;

Expand Down
8 changes: 4 additions & 4 deletions drivers/video/omap2/dss/hdmi_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,17 +347,17 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
case 96000:
case 192000:
if (deep_color == 125)
if (pclk == 27027 || pclk == 74250)
if (pclk == 27027000 || pclk == 74250000)
deep_color_correct = true;
if (deep_color == 150)
if (pclk == 27027)
if (pclk == 27027000)
deep_color_correct = true;
break;
case 44100:
case 88200:
case 176400:
if (deep_color == 125)
if (pclk == 27027)
if (pclk == 27027000)
deep_color_correct = true;
break;
default:
Expand Down Expand Up @@ -418,7 +418,7 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
}
}
/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
*cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);

return 0;
}
Expand Down

0 comments on commit 498f962

Please sign in to comment.