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

Commit 4fbafaf3 authored by Tomi Valkeinen's avatar Tomi Valkeinen
Browse files

OMAP: DSS2: Use PM runtime & HWMOD support



Use PM runtime and HWMOD support to handle enabling and disabling of DSS
modules.

Each DSS module will have get and put functions which can be used to
enable and disable that module. The functions use pm_runtime and hwmod
opt-clocks to enable the hardware.

Acked-by: default avatarKevin Hilman <khilman@ti.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent de3050a7
Loading
Loading
Loading
Loading
+225 −101
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@
#include <linux/hardirq.h>
#include <linux/hardirq.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>


#include <plat/sram.h>
#include <plat/sram.h>
#include <plat/clock.h>
#include <plat/clock.h>
@@ -99,7 +100,11 @@ struct dispc_irq_stats {
static struct {
static struct {
	struct platform_device *pdev;
	struct platform_device *pdev;
	void __iomem    *base;
	void __iomem    *base;

	int		ctx_loss_cnt;

	int irq;
	int irq;
	struct clk *dss_clk;


	u32	fifo_size[3];
	u32	fifo_size[3];


@@ -146,13 +151,12 @@ static inline u32 dispc_read_reg(const u16 idx)
#define RR(reg) \
#define RR(reg) \
	dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)])
	dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)])


void dispc_save_context(void)
static void dispc_save_context(void)
{
{
	int i;
	int i;
	if (cpu_is_omap24xx())
		return;


	SR(SYSCONFIG);
	DSSDBG("dispc_save_context\n");

	SR(IRQENABLE);
	SR(IRQENABLE);
	SR(CONTROL);
	SR(CONTROL);
	SR(CONFIG);
	SR(CONFIG);
@@ -320,10 +324,12 @@ void dispc_save_context(void)
		SR(DIVISOR);
		SR(DIVISOR);
}
}


void dispc_restore_context(void)
static void dispc_restore_context(void)
{
{
	int i;
	int i;
	RR(SYSCONFIG);

	DSSDBG("dispc_restore_context\n");

	/*RR(IRQENABLE);*/
	/*RR(IRQENABLE);*/
	/*RR(CONTROL);*/
	/*RR(CONTROL);*/
	RR(CONFIG);
	RR(CONFIG);
@@ -507,14 +513,82 @@ void dispc_restore_context(void)
#undef SR
#undef SR
#undef RR
#undef RR


static inline void enable_clocks(bool enable)
static void dispc_init_ctx_loss_count(void)
{
{
	if (enable)
	struct device *dev = &dispc.pdev->dev;
		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
	struct omap_display_platform_data *pdata = dev->platform_data;
	else
	struct omap_dss_board_info *board_data = pdata->board_data;
		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
	int cnt = 0;

	/*
	 * get_context_loss_count returns negative on error. We'll ignore the
	 * error and store the error to ctx_loss_cnt, which will cause
	 * dispc_need_ctx_restore() call to return true.
	 */

	if (board_data->get_context_loss_count)
		cnt = board_data->get_context_loss_count(dev);

	WARN_ON(cnt < 0);

	dispc.ctx_loss_cnt = cnt;

	DSSDBG("initial ctx_loss_cnt %u\n", cnt);
}
}


static bool dispc_need_ctx_restore(void)
{
	struct device *dev = &dispc.pdev->dev;
	struct omap_display_platform_data *pdata = dev->platform_data;
	struct omap_dss_board_info *board_data = pdata->board_data;
	int cnt;

	/*
	 * If get_context_loss_count is not available, assume that we need
	 * context restore always.
	 */
	if (!board_data->get_context_loss_count)
		return true;

	cnt = board_data->get_context_loss_count(dev);
	if (cnt < 0) {
		dev_err(dev, "getting context loss count failed, will force "
				"context restore\n");
		dispc.ctx_loss_cnt = cnt;
		return true;
	}

	if (cnt == dispc.ctx_loss_cnt)
		return false;

	DSSDBG("ctx_loss_cnt %d -> %d\n", dispc.ctx_loss_cnt, cnt);
	dispc.ctx_loss_cnt = cnt;

	return true;
}

int dispc_runtime_get(void)
{
	int r;

	DSSDBG("dispc_runtime_get\n");

	r = pm_runtime_get_sync(&dispc.pdev->dev);
	WARN_ON(r < 0);
	return r < 0 ? r : 0;
}

void dispc_runtime_put(void)
{
	int r;

	DSSDBG("dispc_runtime_put\n");

	r = pm_runtime_put(&dispc.pdev->dev);
	WARN_ON(r < 0);
}


bool dispc_go_busy(enum omap_channel channel)
bool dispc_go_busy(enum omap_channel channel)
{
{
	int bit;
	int bit;
@@ -536,7 +610,7 @@ void dispc_go(enum omap_channel channel)
	int bit;
	int bit;
	bool enable_bit, go_bit;
	bool enable_bit, go_bit;


	enable_clocks(1);
	dispc_runtime_get();


	if (channel == OMAP_DSS_CHANNEL_LCD ||
	if (channel == OMAP_DSS_CHANNEL_LCD ||
			channel == OMAP_DSS_CHANNEL_LCD2)
			channel == OMAP_DSS_CHANNEL_LCD2)
@@ -577,7 +651,7 @@ void dispc_go(enum omap_channel channel)
	else
	else
		REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
		REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
end:
end:
	enable_clocks(0);
	dispc_runtime_put();
}
}


static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
@@ -1003,7 +1077,7 @@ static void dispc_set_burst_size(enum omap_plane plane,
{
{
	int shift;
	int shift;


	enable_clocks(1);
	dispc_runtime_get();


	switch (plane) {
	switch (plane) {
	case OMAP_DSS_GFX:
	case OMAP_DSS_GFX:
@@ -1020,7 +1094,7 @@ static void dispc_set_burst_size(enum omap_plane plane,


	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift);
	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift);


	enable_clocks(0);
	dispc_runtime_put();
}
}


static void dispc_configure_burst_sizes(void)
static void dispc_configure_burst_sizes(void)
@@ -1108,9 +1182,9 @@ void dispc_enable_replication(enum omap_plane plane, bool enable)
	else
	else
		bit = 10;
		bit = 10;


	enable_clocks(1);
	dispc_runtime_get();
	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
@@ -1118,9 +1192,9 @@ void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
	u32 val;
	u32 val;
	BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
	BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
	enable_clocks(1);
	dispc_runtime_get();
	dispc_write_reg(DISPC_SIZE_MGR(channel), val);
	dispc_write_reg(DISPC_SIZE_MGR(channel), val);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_set_digit_size(u16 width, u16 height)
void dispc_set_digit_size(u16 width, u16 height)
@@ -1128,9 +1202,9 @@ void dispc_set_digit_size(u16 width, u16 height)
	u32 val;
	u32 val;
	BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
	BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
	enable_clocks(1);
	dispc_runtime_get();
	dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val);
	dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val);
	enable_clocks(0);
	dispc_runtime_put();
}
}


static void dispc_read_plane_fifo_sizes(void)
static void dispc_read_plane_fifo_sizes(void)
@@ -1142,7 +1216,7 @@ static void dispc_read_plane_fifo_sizes(void)


	unit = dss_feat_get_buffer_size_unit();
	unit = dss_feat_get_buffer_size_unit();


	enable_clocks(1);
	dispc_runtime_get();


	dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
	dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);


@@ -1152,7 +1226,7 @@ static void dispc_read_plane_fifo_sizes(void)
		dispc.fifo_size[plane] = size;
		dispc.fifo_size[plane] = size;
	}
	}


	enable_clocks(0);
	dispc_runtime_put();
}
}


u32 dispc_get_plane_fifo_size(enum omap_plane plane)
u32 dispc_get_plane_fifo_size(enum omap_plane plane)
@@ -1176,7 +1250,7 @@ void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
	dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
	dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
	dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
	dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);


	enable_clocks(1);
	dispc_runtime_get();


	DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
	DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
			plane,
			plane,
@@ -1190,17 +1264,17 @@ void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
			FLD_VAL(high, hi_start, hi_end) |
			FLD_VAL(high, hi_start, hi_end) |
			FLD_VAL(low, lo_start, lo_end));
			FLD_VAL(low, lo_start, lo_end));


	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_enable_fifomerge(bool enable)
void dispc_enable_fifomerge(bool enable)
{
{
	enable_clocks(1);
	dispc_runtime_get();


	DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
	DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
	REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
	REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);


	enable_clocks(0);
	dispc_runtime_put();
}
}


static void _dispc_set_fir(enum omap_plane plane,
static void _dispc_set_fir(enum omap_plane plane,
@@ -1822,9 +1896,9 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,


void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out)
void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	_dispc_set_channel_out(plane, channel_out);
	_dispc_set_channel_out(plane, channel_out);
	enable_clocks(0);
	dispc_runtime_put();
}
}


static int _dispc_setup_plane(enum omap_plane plane,
static int _dispc_setup_plane(enum omap_plane plane,
@@ -2020,7 +2094,7 @@ static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
	int r;
	int r;
	u32 irq;
	u32 irq;


	enable_clocks(1);
	dispc_runtime_get();


	/* When we disable LCD output, we need to wait until frame is done.
	/* When we disable LCD output, we need to wait until frame is done.
	 * Otherwise the DSS is still working, and turning off the clocks
	 * Otherwise the DSS is still working, and turning off the clocks
@@ -2056,7 +2130,7 @@ static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
			DSSERR("failed to unregister FRAMEDONE isr\n");
			DSSERR("failed to unregister FRAMEDONE isr\n");
	}
	}


	enable_clocks(0);
	dispc_runtime_put();
}
}


static void _enable_digit_out(bool enable)
static void _enable_digit_out(bool enable)
@@ -2069,10 +2143,10 @@ static void dispc_enable_digit_out(bool enable)
	struct completion frame_done_completion;
	struct completion frame_done_completion;
	int r;
	int r;


	enable_clocks(1);
	dispc_runtime_get();


	if (REG_GET(DISPC_CONTROL, 1, 1) == enable) {
	if (REG_GET(DISPC_CONTROL, 1, 1) == enable) {
		enable_clocks(0);
		dispc_runtime_put();
		return;
		return;
	}
	}


@@ -2127,7 +2201,7 @@ static void dispc_enable_digit_out(bool enable)
		spin_unlock_irqrestore(&dispc.irq_lock, flags);
		spin_unlock_irqrestore(&dispc.irq_lock, flags);
	}
	}


	enable_clocks(0);
	dispc_runtime_put();
}
}


bool dispc_is_channel_enabled(enum omap_channel channel)
bool dispc_is_channel_enabled(enum omap_channel channel)
@@ -2158,9 +2232,9 @@ void dispc_lcd_enable_signal_polarity(bool act_high)
	if (!dss_has_feature(FEAT_LCDENABLEPOL))
	if (!dss_has_feature(FEAT_LCDENABLEPOL))
		return;
		return;


	enable_clocks(1);
	dispc_runtime_get();
	REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
	REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_lcd_enable_signal(bool enable)
void dispc_lcd_enable_signal(bool enable)
@@ -2168,9 +2242,9 @@ void dispc_lcd_enable_signal(bool enable)
	if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
	if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
		return;
		return;


	enable_clocks(1);
	dispc_runtime_get();
	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_pck_free_enable(bool enable)
void dispc_pck_free_enable(bool enable)
@@ -2178,19 +2252,19 @@ void dispc_pck_free_enable(bool enable)
	if (!dss_has_feature(FEAT_PCKFREEENABLE))
	if (!dss_has_feature(FEAT_PCKFREEENABLE))
		return;
		return;


	enable_clocks(1);
	dispc_runtime_get();
	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	if (channel == OMAP_DSS_CHANNEL_LCD2)
	if (channel == OMAP_DSS_CHANNEL_LCD2)
		REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
		REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
	else
	else
		REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
		REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
	enable_clocks(0);
	dispc_runtime_put();
}
}




@@ -2213,27 +2287,27 @@ void dispc_set_lcd_display_type(enum omap_channel channel,
		return;
		return;
	}
	}


	enable_clocks(1);
	dispc_runtime_get();
	if (channel == OMAP_DSS_CHANNEL_LCD2)
	if (channel == OMAP_DSS_CHANNEL_LCD2)
		REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
		REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
	else
	else
		REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
		REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_set_loadmode(enum omap_dss_load_mode mode)
void dispc_set_loadmode(enum omap_dss_load_mode mode)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1);
	REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1);
	enable_clocks(0);
	dispc_runtime_put();
}
}




void dispc_set_default_color(enum omap_channel channel, u32 color)
void dispc_set_default_color(enum omap_channel channel, u32 color)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
	dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
	enable_clocks(0);
	dispc_runtime_put();
}
}


u32 dispc_get_default_color(enum omap_channel channel)
u32 dispc_get_default_color(enum omap_channel channel)
@@ -2244,9 +2318,9 @@ u32 dispc_get_default_color(enum omap_channel channel)
		channel != OMAP_DSS_CHANNEL_LCD &&
		channel != OMAP_DSS_CHANNEL_LCD &&
		channel != OMAP_DSS_CHANNEL_LCD2);
		channel != OMAP_DSS_CHANNEL_LCD2);


	enable_clocks(1);
	dispc_runtime_get();
	l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
	l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
	enable_clocks(0);
	dispc_runtime_put();


	return l;
	return l;
}
}
@@ -2255,7 +2329,7 @@ void dispc_set_trans_key(enum omap_channel ch,
		enum omap_dss_trans_key_type type,
		enum omap_dss_trans_key_type type,
		u32 trans_key)
		u32 trans_key)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	if (ch == OMAP_DSS_CHANNEL_LCD)
	if (ch == OMAP_DSS_CHANNEL_LCD)
		REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
		REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
@@ -2264,14 +2338,14 @@ void dispc_set_trans_key(enum omap_channel ch,
		REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
		REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);


	dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
	dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_get_trans_key(enum omap_channel ch,
void dispc_get_trans_key(enum omap_channel ch,
		enum omap_dss_trans_key_type *type,
		enum omap_dss_trans_key_type *type,
		u32 *trans_key)
		u32 *trans_key)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	if (type) {
	if (type) {
		if (ch == OMAP_DSS_CHANNEL_LCD)
		if (ch == OMAP_DSS_CHANNEL_LCD)
			*type = REG_GET(DISPC_CONFIG, 11, 11);
			*type = REG_GET(DISPC_CONFIG, 11, 11);
@@ -2285,33 +2359,33 @@ void dispc_get_trans_key(enum omap_channel ch,


	if (trans_key)
	if (trans_key)
		*trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
		*trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_enable_trans_key(enum omap_channel ch, bool enable)
void dispc_enable_trans_key(enum omap_channel ch, bool enable)
{
{
	enable_clocks(1);
	dispc_runtime_get();
	if (ch == OMAP_DSS_CHANNEL_LCD)
	if (ch == OMAP_DSS_CHANNEL_LCD)
		REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
		REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
		REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
		REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
	else /* OMAP_DSS_CHANNEL_LCD2 */
	else /* OMAP_DSS_CHANNEL_LCD2 */
		REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
		REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
	enable_clocks(0);
	dispc_runtime_put();
}
}
void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
{
{
	if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
	if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
		return;
		return;


	enable_clocks(1);
	dispc_runtime_get();
	if (ch == OMAP_DSS_CHANNEL_LCD)
	if (ch == OMAP_DSS_CHANNEL_LCD)
		REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
		REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
		REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
		REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
	else /* OMAP_DSS_CHANNEL_LCD2 */
	else /* OMAP_DSS_CHANNEL_LCD2 */
		REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
		REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
	enable_clocks(0);
	dispc_runtime_put();
}
}
bool dispc_alpha_blending_enabled(enum omap_channel ch)
bool dispc_alpha_blending_enabled(enum omap_channel ch)
{
{
@@ -2320,7 +2394,7 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch)
	if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
	if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
		return false;
		return false;


	enable_clocks(1);
	dispc_runtime_get();
	if (ch == OMAP_DSS_CHANNEL_LCD)
	if (ch == OMAP_DSS_CHANNEL_LCD)
		enabled = REG_GET(DISPC_CONFIG, 18, 18);
		enabled = REG_GET(DISPC_CONFIG, 18, 18);
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
@@ -2329,7 +2403,7 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch)
		enabled = REG_GET(DISPC_CONFIG2, 18, 18);
		enabled = REG_GET(DISPC_CONFIG2, 18, 18);
	else
	else
		BUG();
		BUG();
	enable_clocks(0);
	dispc_runtime_put();


	return enabled;
	return enabled;
}
}
@@ -2339,7 +2413,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
{
{
	bool enabled;
	bool enabled;


	enable_clocks(1);
	dispc_runtime_get();
	if (ch == OMAP_DSS_CHANNEL_LCD)
	if (ch == OMAP_DSS_CHANNEL_LCD)
		enabled = REG_GET(DISPC_CONFIG, 10, 10);
		enabled = REG_GET(DISPC_CONFIG, 10, 10);
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
@@ -2348,7 +2422,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
		enabled = REG_GET(DISPC_CONFIG2, 10, 10);
		enabled = REG_GET(DISPC_CONFIG2, 10, 10);
	else
	else
		BUG();
		BUG();
	enable_clocks(0);
	dispc_runtime_put();


	return enabled;
	return enabled;
}
}
@@ -2376,12 +2450,12 @@ void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
		return;
		return;
	}
	}


	enable_clocks(1);
	dispc_runtime_get();
	if (channel == OMAP_DSS_CHANNEL_LCD2)
	if (channel == OMAP_DSS_CHANNEL_LCD2)
		REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
		REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
	else
	else
		REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
		REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_set_parallel_interface_mode(enum omap_channel channel,
void dispc_set_parallel_interface_mode(enum omap_channel channel,
@@ -2413,7 +2487,7 @@ void dispc_set_parallel_interface_mode(enum omap_channel channel,
		return;
		return;
	}
	}


	enable_clocks(1);
	dispc_runtime_get();


	if (channel == OMAP_DSS_CHANNEL_LCD2) {
	if (channel == OMAP_DSS_CHANNEL_LCD2) {
		l = dispc_read_reg(DISPC_CONTROL2);
		l = dispc_read_reg(DISPC_CONTROL2);
@@ -2427,7 +2501,7 @@ void dispc_set_parallel_interface_mode(enum omap_channel channel,
		dispc_write_reg(DISPC_CONTROL, l);
		dispc_write_reg(DISPC_CONTROL, l);
	}
	}


	enable_clocks(0);
	dispc_runtime_put();
}
}


static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -2480,10 +2554,10 @@ static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
			FLD_VAL(vbp, 31, 20);
			FLD_VAL(vbp, 31, 20);
	}
	}


	enable_clocks(1);
	dispc_runtime_get();
	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
	enable_clocks(0);
	dispc_runtime_put();
}
}


/* change name to mode? */
/* change name to mode? */
@@ -2526,10 +2600,10 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
	BUG_ON(lck_div < 1);
	BUG_ON(lck_div < 1);
	BUG_ON(pck_div < 2);
	BUG_ON(pck_div < 2);


	enable_clocks(1);
	dispc_runtime_get();
	dispc_write_reg(DISPC_DIVISORo(channel),
	dispc_write_reg(DISPC_DIVISORo(channel),
			FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
			FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
	enable_clocks(0);
	dispc_runtime_put();
}
}


static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
@@ -2548,7 +2622,7 @@ unsigned long dispc_fclk_rate(void)


	switch (dss_get_dispc_clk_source()) {
	switch (dss_get_dispc_clk_source()) {
	case OMAP_DSS_CLK_SRC_FCK:
	case OMAP_DSS_CLK_SRC_FCK:
		r = dss_clk_get_rate(DSS_CLK_FCK);
		r = clk_get_rate(dispc.dss_clk);
		break;
		break;
	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
		dsidev = dsi_get_dsidev_from_id(0);
		dsidev = dsi_get_dsidev_from_id(0);
@@ -2578,7 +2652,7 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)


	switch (dss_get_lcd_clk_source(channel)) {
	switch (dss_get_lcd_clk_source(channel)) {
	case OMAP_DSS_CLK_SRC_FCK:
	case OMAP_DSS_CLK_SRC_FCK:
		r = dss_clk_get_rate(DSS_CLK_FCK);
		r = clk_get_rate(dispc.dss_clk);
		break;
		break;
	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
		dsidev = dsi_get_dsidev_from_id(0);
		dsidev = dsi_get_dsidev_from_id(0);
@@ -2617,7 +2691,8 @@ void dispc_dump_clocks(struct seq_file *s)
	enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
	enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
	enum omap_dss_clk_source lcd_clk_src;
	enum omap_dss_clk_source lcd_clk_src;


	enable_clocks(1);
	if (dispc_runtime_get())
		return;


	seq_printf(s, "- DISPC -\n");
	seq_printf(s, "- DISPC -\n");


@@ -2665,7 +2740,8 @@ void dispc_dump_clocks(struct seq_file *s)
		seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
		seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
				dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
				dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
	}
	}
	enable_clocks(0);

	dispc_runtime_put();
}
}


#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -2720,7 +2796,8 @@ void dispc_dump_regs(struct seq_file *s)
{
{
#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))


	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
	if (dispc_runtime_get())
		return;


	DUMPREG(DISPC_REVISION);
	DUMPREG(DISPC_REVISION);
	DUMPREG(DISPC_SYSCONFIG);
	DUMPREG(DISPC_SYSCONFIG);
@@ -2965,7 +3042,7 @@ void dispc_dump_regs(struct seq_file *s)
		DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
		DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
	}
	}


	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
	dispc_runtime_put();
#undef DUMPREG
#undef DUMPREG
}
}


@@ -2986,9 +3063,9 @@ static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
	l |= FLD_VAL(acbi, 11, 8);
	l |= FLD_VAL(acbi, 11, 8);
	l |= FLD_VAL(acb, 7, 0);
	l |= FLD_VAL(acb, 7, 0);


	enable_clocks(1);
	dispc_runtime_get();
	dispc_write_reg(DISPC_POL_FREQ(channel), l);
	dispc_write_reg(DISPC_POL_FREQ(channel), l);
	enable_clocks(0);
	dispc_runtime_put();
}
}


void dispc_set_pol_freq(enum omap_channel channel,
void dispc_set_pol_freq(enum omap_channel channel,
@@ -3109,7 +3186,7 @@ static void _omap_dispc_set_irqs(void)
		mask |= isr_data->mask;
		mask |= isr_data->mask;
	}
	}


	enable_clocks(1);
	dispc_runtime_get();


	old_mask = dispc_read_reg(DISPC_IRQENABLE);
	old_mask = dispc_read_reg(DISPC_IRQENABLE);
	/* clear the irqstatus for newly enabled irqs */
	/* clear the irqstatus for newly enabled irqs */
@@ -3117,7 +3194,7 @@ static void _omap_dispc_set_irqs(void)


	dispc_write_reg(DISPC_IRQENABLE, mask);
	dispc_write_reg(DISPC_IRQENABLE, mask);


	enable_clocks(0);
	dispc_runtime_put();
}
}


int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
@@ -3626,13 +3703,6 @@ static void _omap_dispc_initial_config(void)
{
{
	u32 l;
	u32 l;


	l = dispc_read_reg(DISPC_SYSCONFIG);
	l = FLD_MOD(l, 2, 13, 12);	/* MIDLEMODE: smart standby */
	l = FLD_MOD(l, 2, 4, 3);	/* SIDLEMODE: smart idle */
	l = FLD_MOD(l, 1, 2, 2);	/* ENWAKEUP */
	l = FLD_MOD(l, 1, 0, 0);	/* AUTOIDLE */
	dispc_write_reg(DISPC_SYSCONFIG, l);

	/* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
	/* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
	if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
	if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
		l = dispc_read_reg(DISPC_DIVISOR);
		l = dispc_read_reg(DISPC_DIVISOR);
@@ -3664,9 +3734,9 @@ int dispc_enable_plane(enum omap_plane plane, bool enable)
{
{
	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);


	enable_clocks(1);
	dispc_runtime_get();
	_dispc_enable_plane(plane, enable);
	_dispc_enable_plane(plane, enable);
	enable_clocks(0);
	dispc_runtime_put();


	return 0;
	return 0;
}
}
@@ -3693,7 +3763,7 @@ int dispc_setup_plane(enum omap_plane plane,
	       ilace, color_mode,
	       ilace, color_mode,
	       rotation, mirror, channel);
	       rotation, mirror, channel);


	enable_clocks(1);
	dispc_runtime_get();


	r = _dispc_setup_plane(plane,
	r = _dispc_setup_plane(plane,
			   paddr, screen_width,
			   paddr, screen_width,
@@ -3707,7 +3777,7 @@ int dispc_setup_plane(enum omap_plane plane,
			   pre_mult_alpha,
			   pre_mult_alpha,
			   channel, puv_addr);
			   channel, puv_addr);


	enable_clocks(0);
	dispc_runtime_put();


	return r;
	return r;
}
}
@@ -3718,9 +3788,19 @@ static int omap_dispchw_probe(struct platform_device *pdev)
	u32 rev;
	u32 rev;
	int r = 0;
	int r = 0;
	struct resource *dispc_mem;
	struct resource *dispc_mem;
	struct clk *clk;


	dispc.pdev = pdev;
	dispc.pdev = pdev;


	clk = clk_get(&pdev->dev, "fck");
	if (IS_ERR(clk)) {
		DSSERR("can't get fck\n");
		r = PTR_ERR(clk);
		goto err_get_clk;
	}

	dispc.dss_clk = clk;

	spin_lock_init(&dispc.irq_lock);
	spin_lock_init(&dispc.irq_lock);


#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -3734,62 +3814,106 @@ static int omap_dispchw_probe(struct platform_device *pdev)
	if (!dispc_mem) {
	if (!dispc_mem) {
		DSSERR("can't get IORESOURCE_MEM DISPC\n");
		DSSERR("can't get IORESOURCE_MEM DISPC\n");
		r = -EINVAL;
		r = -EINVAL;
		goto fail0;
		goto err_ioremap;
	}
	}
	dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
	dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
	if (!dispc.base) {
	if (!dispc.base) {
		DSSERR("can't ioremap DISPC\n");
		DSSERR("can't ioremap DISPC\n");
		r = -ENOMEM;
		r = -ENOMEM;
		goto fail0;
		goto err_ioremap;
	}
	}
	dispc.irq = platform_get_irq(dispc.pdev, 0);
	dispc.irq = platform_get_irq(dispc.pdev, 0);
	if (dispc.irq < 0) {
	if (dispc.irq < 0) {
		DSSERR("platform_get_irq failed\n");
		DSSERR("platform_get_irq failed\n");
		r = -ENODEV;
		r = -ENODEV;
		goto fail1;
		goto err_irq;
	}
	}


	r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
	r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
		"OMAP DISPC", dispc.pdev);
		"OMAP DISPC", dispc.pdev);
	if (r < 0) {
	if (r < 0) {
		DSSERR("request_irq failed\n");
		DSSERR("request_irq failed\n");
		goto fail1;
		goto err_irq;
	}
	}


	enable_clocks(1);
	dispc_init_ctx_loss_count();

	pm_runtime_enable(&pdev->dev);

	r = dispc_runtime_get();
	if (r)
		goto err_runtime_get;


	_omap_dispc_initial_config();
	_omap_dispc_initial_config();


	_omap_dispc_initialize_irq();
	_omap_dispc_initialize_irq();


	dispc_save_context();

	rev = dispc_read_reg(DISPC_REVISION);
	rev = dispc_read_reg(DISPC_REVISION);
	dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
	dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));


	enable_clocks(0);
	dispc_runtime_put();


	return 0;
	return 0;
fail1:

err_runtime_get:
	pm_runtime_disable(&pdev->dev);
	free_irq(dispc.irq, dispc.pdev);
err_irq:
	iounmap(dispc.base);
	iounmap(dispc.base);
fail0:
err_ioremap:
	clk_put(dispc.dss_clk);
err_get_clk:
	return r;
	return r;
}
}


static int omap_dispchw_remove(struct platform_device *pdev)
static int omap_dispchw_remove(struct platform_device *pdev)
{
{
	pm_runtime_disable(&pdev->dev);

	clk_put(dispc.dss_clk);

	free_irq(dispc.irq, dispc.pdev);
	free_irq(dispc.irq, dispc.pdev);
	iounmap(dispc.base);
	iounmap(dispc.base);
	return 0;
	return 0;
}
}


static int dispc_runtime_suspend(struct device *dev)
{
	dispc_save_context();
	clk_disable(dispc.dss_clk);
	dss_runtime_put();

	return 0;
}

static int dispc_runtime_resume(struct device *dev)
{
	int r;

	r = dss_runtime_get();
	if (r < 0)
		return r;

	clk_enable(dispc.dss_clk);
	if (dispc_need_ctx_restore())
		dispc_restore_context();

	return 0;
}

static const struct dev_pm_ops dispc_pm_ops = {
	.runtime_suspend = dispc_runtime_suspend,
	.runtime_resume = dispc_runtime_resume,
};

static struct platform_driver omap_dispchw_driver = {
static struct platform_driver omap_dispchw_driver = {
	.probe          = omap_dispchw_probe,
	.probe          = omap_dispchw_probe,
	.remove         = omap_dispchw_remove,
	.remove         = omap_dispchw_remove,
	.driver         = {
	.driver         = {
		.name   = "omapdss_dispc",
		.name   = "omapdss_dispc",
		.owner  = THIS_MODULE,
		.owner  = THIS_MODULE,
		.pm	= &dispc_pm_ops,
	},
	},
};
};


+47 −23
Original line number Original line Diff line number Diff line
@@ -23,7 +23,6 @@
#define DSS_SUBSYS_NAME "DPI"
#define DSS_SUBSYS_NAME "DPI"


#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/errno.h>
@@ -130,8 +129,6 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
	bool is_tft;
	bool is_tft;
	int r = 0;
	int r = 0;


	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);

	dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
	dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
			dssdev->panel.acbi, dssdev->panel.acb);
			dssdev->panel.acbi, dssdev->panel.acb);


@@ -144,7 +141,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
		r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
		r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
				&fck, &lck_div, &pck_div);
				&fck, &lck_div, &pck_div);
	if (r)
	if (r)
		goto err0;
		return r;


	pck = fck / lck_div / pck_div / 1000;
	pck = fck / lck_div / pck_div / 1000;


@@ -158,12 +155,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)


	dispc_set_lcd_timings(dssdev->manager->id, t);
	dispc_set_lcd_timings(dssdev->manager->id, t);


err0:
	return 0;
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
	return r;
}
}


static int dpi_basic_init(struct omap_dss_device *dssdev)
static void dpi_basic_init(struct omap_dss_device *dssdev)
{
{
	bool is_tft;
	bool is_tft;


@@ -175,8 +170,6 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
			OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
			OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
	dispc_set_tft_data_lines(dssdev->manager->id,
	dispc_set_tft_data_lines(dssdev->manager->id,
			dssdev->phy.dpi.data_lines);
			dssdev->phy.dpi.data_lines);

	return 0;
}
}


int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
@@ -186,30 +179,38 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
	r = omap_dss_start_device(dssdev);
	r = omap_dss_start_device(dssdev);
	if (r) {
	if (r) {
		DSSERR("failed to start device\n");
		DSSERR("failed to start device\n");
		goto err0;
		goto err_start_dev;
	}
	}


	if (cpu_is_omap34xx()) {
	if (cpu_is_omap34xx()) {
		r = regulator_enable(dpi.vdds_dsi_reg);
		r = regulator_enable(dpi.vdds_dsi_reg);
		if (r)
		if (r)
			goto err1;
			goto err_reg_enable;
	}
	}


	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
	r = dss_runtime_get();
	if (r)
		goto err_get_dss;


	r = dpi_basic_init(dssdev);
	r = dispc_runtime_get();
	if (r)
	if (r)
		goto err2;
		goto err_get_dispc;

	dpi_basic_init(dssdev);


	if (dpi_use_dsi_pll(dssdev)) {
	if (dpi_use_dsi_pll(dssdev)) {
		r = dsi_runtime_get(dpi.dsidev);
		if (r)
			goto err_get_dsi;

		r = dsi_pll_init(dpi.dsidev, 0, 1);
		r = dsi_pll_init(dpi.dsidev, 0, 1);
		if (r)
		if (r)
			goto err2;
			goto err_dsi_pll_init;
	}
	}


	r = dpi_set_mode(dssdev);
	r = dpi_set_mode(dssdev);
	if (r)
	if (r)
		goto err3;
		goto err_set_mode;


	mdelay(2);
	mdelay(2);


@@ -217,16 +218,22 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)


	return 0;
	return 0;


err3:
err_set_mode:
	if (dpi_use_dsi_pll(dssdev))
	if (dpi_use_dsi_pll(dssdev))
		dsi_pll_uninit(dpi.dsidev, true);
		dsi_pll_uninit(dpi.dsidev, true);
err2:
err_dsi_pll_init:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
	if (dpi_use_dsi_pll(dssdev))
		dsi_runtime_put(dpi.dsidev);
err_get_dsi:
	dispc_runtime_put();
err_get_dispc:
	dss_runtime_put();
err_get_dss:
	if (cpu_is_omap34xx())
	if (cpu_is_omap34xx())
		regulator_disable(dpi.vdds_dsi_reg);
		regulator_disable(dpi.vdds_dsi_reg);
err1:
err_reg_enable:
	omap_dss_stop_device(dssdev);
	omap_dss_stop_device(dssdev);
err0:
err_start_dev:
	return r;
	return r;
}
}
EXPORT_SYMBOL(omapdss_dpi_display_enable);
EXPORT_SYMBOL(omapdss_dpi_display_enable);
@@ -238,9 +245,11 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
	if (dpi_use_dsi_pll(dssdev)) {
	if (dpi_use_dsi_pll(dssdev)) {
		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
		dsi_pll_uninit(dpi.dsidev, true);
		dsi_pll_uninit(dpi.dsidev, true);
		dsi_runtime_put(dpi.dsidev);
	}
	}


	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
	dispc_runtime_put();
	dss_runtime_put();


	if (cpu_is_omap34xx())
	if (cpu_is_omap34xx())
		regulator_disable(dpi.vdds_dsi_reg);
		regulator_disable(dpi.vdds_dsi_reg);
@@ -252,11 +261,26 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
void dpi_set_timings(struct omap_dss_device *dssdev,
void dpi_set_timings(struct omap_dss_device *dssdev,
			struct omap_video_timings *timings)
			struct omap_video_timings *timings)
{
{
	int r;

	DSSDBG("dpi_set_timings\n");
	DSSDBG("dpi_set_timings\n");
	dssdev->panel.timings = *timings;
	dssdev->panel.timings = *timings;
	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
		r = dss_runtime_get();
		if (r)
			return;

		r = dispc_runtime_get();
		if (r) {
			dss_runtime_put();
			return;
		}

		dpi_set_mode(dssdev);
		dpi_set_mode(dssdev);
		dispc_go(dssdev->manager->id);
		dispc_go(dssdev->manager->id);

		dispc_runtime_put();
		dss_runtime_put();
	}
	}
}
}
EXPORT_SYMBOL(dpi_set_timings);
EXPORT_SYMBOL(dpi_set_timings);
+155 −89

File changed.

Preview size limit exceeded, changes collapsed.

+77 −299

File changed.

Preview size limit exceeded, changes collapsed.

+15 −18
Original line number Original line Diff line number Diff line
@@ -103,14 +103,6 @@ enum omap_parallel_interface_mode {
	OMAP_DSS_PARALLELMODE_DSI,
	OMAP_DSS_PARALLELMODE_DSI,
};
};


enum dss_clock {
	DSS_CLK_ICK	= 1 << 0,	/* DSS_L3_ICLK and DSS_L4_ICLK */
	DSS_CLK_FCK	= 1 << 1,	/* DSS1_ALWON_FCLK */
	DSS_CLK_SYSCK	= 1 << 2,	/* DSS2_ALWON_FCLK */
	DSS_CLK_TVFCK	= 1 << 3,	/* DSS_TV_FCLK */
	DSS_CLK_VIDFCK	= 1 << 4,	/* DSS_96M_FCLK*/
};

enum dss_hdmi_venc_clk_source_select {
enum dss_hdmi_venc_clk_source_select {
	DSS_VENC_TV_CLK = 0,
	DSS_VENC_TV_CLK = 0,
	DSS_HDMI_M_PCLK = 1,
	DSS_HDMI_M_PCLK = 1,
@@ -214,12 +206,10 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
int dss_init_platform_driver(void);
int dss_init_platform_driver(void);
void dss_uninit_platform_driver(void);
void dss_uninit_platform_driver(void);


int dss_runtime_get(void);
void dss_runtime_put(void);

void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
void dss_save_context(void);
void dss_restore_context(void);
void dss_clk_enable(enum dss_clock clks);
void dss_clk_disable(enum dss_clock clks);
unsigned long dss_clk_get_rate(enum dss_clock clk);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
void dss_dump_clocks(struct seq_file *s);
void dss_dump_clocks(struct seq_file *s);


@@ -276,15 +266,15 @@ struct file_operations;
int dsi_init_platform_driver(void);
int dsi_init_platform_driver(void);
void dsi_uninit_platform_driver(void);
void dsi_uninit_platform_driver(void);


int dsi_runtime_get(struct platform_device *dsidev);
void dsi_runtime_put(struct platform_device *dsidev);

void dsi_dump_clocks(struct seq_file *s);
void dsi_dump_clocks(struct seq_file *s);
void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
		const struct file_operations *debug_fops);
		const struct file_operations *debug_fops);
void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
		const struct file_operations *debug_fops);
		const struct file_operations *debug_fops);


void dsi_save_context(void);
void dsi_restore_context(void);

int dsi_init_display(struct omap_dss_device *display);
int dsi_init_display(struct omap_dss_device *display);
void dsi_irq_handler(void);
void dsi_irq_handler(void);
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
@@ -310,6 +300,13 @@ static inline int dsi_init_platform_driver(void)
static inline void dsi_uninit_platform_driver(void)
static inline void dsi_uninit_platform_driver(void)
{
{
}
}
static inline int dsi_runtime_get(struct platform_device *dsidev)
{
	return 0;
}
static inline void dsi_runtime_put(struct platform_device *dsidev)
{
}
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
{
{
	WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
	WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
@@ -377,8 +374,8 @@ void dispc_dump_regs(struct seq_file *s);
void dispc_irq_handler(void);
void dispc_irq_handler(void);
void dispc_fake_vsync_irq(void);
void dispc_fake_vsync_irq(void);


void dispc_save_context(void);
int dispc_runtime_get(void);
void dispc_restore_context(void);
void dispc_runtime_put(void);


void dispc_enable_sidle(void);
void dispc_enable_sidle(void);
void dispc_disable_sidle(void);
void dispc_disable_sidle(void);
Loading