Skip to content

Commit

Permalink
sh_mobile_meram: MERAM framework for LCDC
Browse files Browse the repository at this point in the history
Based on the patch by Takanari Hayama <[email protected]>

Adds support framework necessary to use Media RAM (MERAM)
caching functionality with the LCDC.  The MERAM is accessed
through up to 4 Interconnect Buffers (ICBs).

ICB numbers and MERAM address ranges to use are specified in
by filling in the .meram_cfg member of the LCDC platform data

Signed-off-by: Damian Hobson-Garcia <[email protected]>
Signed-off-by: Paul Mundt <[email protected]>
  • Loading branch information
dhobsong authored and pmundt committed May 23, 2011
1 parent 71a8638 commit 7caa434
Show file tree
Hide file tree
Showing 8 changed files with 772 additions and 9 deletions.
12 changes: 12 additions & 0 deletions drivers/video/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,18 @@ config FB_SH_MOBILE_HDMI
---help---
Driver for the on-chip SH-Mobile HDMI controller.

config FB_SH_MOBILE_MERAM
tristate "SuperH Mobile MERAM read ahead support for LCDC"
depends on FB_SH_MOBILE_LCDC
default y
---help---
Enable MERAM support for the SH-Mobile LCD controller.

This will allow for caching of the framebuffer to provide more
reliable access under heavy main memory bus traffic situations.
Up to 4 memory channels can be configured, allowing 4 RGB or
2 YCbCr framebuffers to be configured.

config FB_TMIO
tristate "Toshiba Mobile IO FrameBuffer support"
depends on FB && MFD_CORE
Expand Down
1 change: 1 addition & 0 deletions drivers/video/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ obj-$(CONFIG_FB_UDL) += udlfb.o
obj-$(CONFIG_FB_XILINX) += xilinxfb.o
obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
obj-$(CONFIG_FB_OMAP) += omap/
obj-y += omap2/
Expand Down
103 changes: 94 additions & 9 deletions drivers/video/sh_mobile_lcdcfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <asm/atomic.h>

#include "sh_mobile_lcdcfb.h"
#include "sh_mobile_meram.h"

#define SIDE_B_OFFSET 0x1000
#define MIRROR_OFFSET 0x2000
Expand Down Expand Up @@ -143,6 +144,7 @@ struct sh_mobile_lcdc_priv {
unsigned long saved_shared_regs[NR_SHARED_REGS];
int started;
int forced_bpp; /* 2 channel LCDC must share bpp setting */
struct sh_mobile_meram_info *meram_dev;
};

static bool banked(int reg_nr)
Expand Down Expand Up @@ -564,6 +566,9 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
}

for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
unsigned long base_addr_y;
unsigned long base_addr_c = 0;
int pitch;
ch = &priv->ch[k];

if (!priv->ch[k].enabled)
Expand Down Expand Up @@ -598,16 +603,63 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
}
lcdc_write_chan(ch, LDDFR, tmp);

base_addr_y = ch->info->fix.smem_start;
base_addr_c = base_addr_y +
ch->info->var.xres *
ch->info->var.yres_virtual;
pitch = ch->info->fix.line_length;

/* test if we can enable meram */
if (ch->cfg.meram_cfg && priv->meram_dev) {
struct sh_mobile_meram_cfg *cfg;
struct sh_mobile_meram_info *mdev;
unsigned long icb_addr_y, icb_addr_c;
int icb_pitch;
int pf;

cfg = ch->cfg.meram_cfg;
mdev = priv->meram_dev;
/* we need to de-init configured ICBs before we
* we can re-initialize them.
*/
if (ch->meram_enabled)
mdev->ops->meram_unregister(mdev, cfg);

ch->meram_enabled = 0;

if (ch->info->var.nonstd)
pf = SH_MOBILE_MERAM_PF_NV;
else
pf = SH_MOBILE_MERAM_PF_RGB;

ret = mdev->ops->meram_register(mdev, cfg, pitch,
ch->info->var.yres,
pf,
base_addr_y,
base_addr_c,
&icb_addr_y,
&icb_addr_c,
&icb_pitch);
if (!ret) {
/* set LDSA1R value */
base_addr_y = icb_addr_y;
pitch = icb_pitch;

/* set LDSA2R value if required */
if (base_addr_c)
base_addr_c = icb_addr_c;

ch->meram_enabled = 1;
}
}

/* point out our frame buffer */
lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
lcdc_write_chan(ch, LDSA1R, base_addr_y);
if (ch->info->var.nonstd)
lcdc_write_chan(ch, LDSA2R,
ch->info->fix.smem_start +
ch->info->var.xres *
ch->info->var.yres_virtual);
lcdc_write_chan(ch, LDSA2R, base_addr_c);

/* set line size */
lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
lcdc_write_chan(ch, LDMLSR, pitch);

/* setup deferred io if SYS bus */
tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
Expand Down Expand Up @@ -692,6 +744,17 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
board_cfg->display_off(board_cfg->board_data);
module_put(board_cfg->owner);
}

/* disable the meram */
if (ch->meram_enabled) {
struct sh_mobile_meram_cfg *cfg;
struct sh_mobile_meram_info *mdev;
cfg = ch->cfg.meram_cfg;
mdev = priv->meram_dev;
mdev->ops->meram_unregister(mdev, cfg);
ch->meram_enabled = 0;
}

}

/* stop the lcdc */
Expand Down Expand Up @@ -875,9 +938,29 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
} else
base_addr_c = 0;

lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
if (base_addr_c)
lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
if (!ch->meram_enabled) {
lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
if (base_addr_c)
lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
} else {
struct sh_mobile_meram_cfg *cfg;
struct sh_mobile_meram_info *mdev;
unsigned long icb_addr_y, icb_addr_c;
int ret;

cfg = ch->cfg.meram_cfg;
mdev = priv->meram_dev;
ret = mdev->ops->meram_update(mdev, cfg,
base_addr_y, base_addr_c,
&icb_addr_y, &icb_addr_c);
if (ret)
return ret;

lcdc_write_chan_mirror(ch, LDSA1R, icb_addr_y);
if (icb_addr_c)
lcdc_write_chan_mirror(ch, LDSA2R, icb_addr_c);

}

if (lcdc_chan_is_sublcd(ch))
lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
Expand Down Expand Up @@ -1420,6 +1503,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
goto err1;
}

priv->meram_dev = pdata->meram_dev;

for (i = 0; i < j; i++) {
struct fb_var_screeninfo *var;
const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
Expand Down
1 change: 1 addition & 0 deletions drivers/video/sh_mobile_lcdcfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct sh_mobile_lcdc_chan {
int use_count;
int blank_status;
struct mutex open_lock; /* protects the use counter */
int meram_enabled;
};

#endif
Loading

0 comments on commit 7caa434

Please sign in to comment.