Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d15660a1 authored by Paul Mundt's avatar Paul Mundt
Browse files

Merge branches 'common/fbdev' and 'common/fbdev-meram' of...

Merge branches 'common/fbdev' and 'common/fbdev-meram' of master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1991,6 +1991,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
+1 −0
Original line number Diff line number Diff line
@@ -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/
+8 −2
Original line number Diff line number Diff line
@@ -1131,15 +1131,19 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
		pm_runtime_get_sync(hdmi->dev);

		ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
		if (ret < 0)
		if (ret < 0) {
			pm_runtime_put(hdmi->dev);
			goto out;
		}

		hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;

		/* Reconfigure the clock */
		ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
		if (ret < 0)
		if (ret < 0) {
			pm_runtime_put(hdmi->dev);
			goto out;
		}

		msleep(10);
		sh_hdmi_configure(hdmi);
@@ -1336,6 +1340,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
ecodec:
	free_irq(irq, hdmi);
ereqirq:
	pm_runtime_suspend(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	iounmap(hdmi->base);
emap:
@@ -1372,6 +1377,7 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
	free_irq(irq, hdmi);
	/* Wait for already scheduled work */
	cancel_delayed_work_sync(&hdmi->edid_work);
	pm_runtime_suspend(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	clk_disable(hdmi->hdmi_clk);
	clk_put(hdmi->hdmi_clk);
+105 −20
Original line number Diff line number Diff line
@@ -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
@@ -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)
@@ -469,7 +471,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
	int bpp = 0;
	unsigned long ldddsr;
	int k, m;
	int ret = 0;

	/* enable clocks before accessing the hardware */
	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -538,12 +539,13 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
		lcdc_write_chan(ch, LDPMR, 0);

		board_cfg = &ch->cfg.board_cfg;
		if (board_cfg->setup_sys)
			ret = board_cfg->setup_sys(board_cfg->board_data, ch,
						   &sh_mobile_lcdc_sys_bus_ops);
		if (board_cfg->setup_sys) {
			int ret = board_cfg->setup_sys(board_cfg->board_data,
						ch, &sh_mobile_lcdc_sys_bus_ops);
			if (ret)
				return ret;
		}
	}

	/* word and long word swap */
	ldddsr = lcdc_read(priv, _LDDDSR);
@@ -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)
@@ -598,16 +603,67 @@ 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) {
				if (ch->info->var.bits_per_pixel == 24)
					pf = SH_MOBILE_MERAM_PF_NV24;
				else
					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;
@@ -692,6 +748,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 */
@@ -875,9 +942,29 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
	} else
		base_addr_c = 0;

	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);
@@ -1288,7 +1375,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
	struct fb_info *info = event->info;
	struct sh_mobile_lcdc_chan *ch = info->par;
	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
	int ret;

	if (&ch->lcdc->notifier != nb)
		return NOTIFY_DONE;
@@ -1302,7 +1388,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
			board_cfg->display_off(board_cfg->board_data);
			module_put(board_cfg->owner);
		}
		pm_runtime_put(info->device);
		sh_mobile_lcdc_stop(ch->lcdc);
		break;
	case FB_EVENT_RESUME:
@@ -1316,9 +1401,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
			module_put(board_cfg->owner);
		}

		ret = sh_mobile_lcdc_start(ch->lcdc);
		if (!ret)
			pm_runtime_get_sync(info->device);
		sh_mobile_lcdc_start(ch->lcdc);
	}

	return NOTIFY_OK;
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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