Example #1
0
static void sossi_stop_transfer(void)
{
	/* WE */
	sossi_set_bits(SOSSI_INIT2_REG, 1 << 4);
	/* CS active low */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 30);
	/* FIXME: locking? */
}
Example #2
0
static void sossi_read_data(void *data, unsigned int len)
{
	clk_enable(sossi.fck);
	set_timing(RD_ACCESS);
	_set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width);
	/* CMD#/DATA */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
	set_cycles(len);
	sossi_start_transfer();
	while (len >= 4) {
		*(u32 *) data = sossi_read_reg(SOSSI_FIFO_REG);
		len -= 4;
		data += 4;
	}
	while (len >= 2) {
		*(u16 *) data = sossi_read_reg16(SOSSI_FIFO_REG);
		len -= 2;
		data += 2;
	}
	while (len) {
		*(u8 *) data = sossi_read_reg8(SOSSI_FIFO_REG);
		len--;
		data++;
	}
	sossi_stop_transfer();
	clk_disable(sossi.fck);
}
Example #3
0
static void sossi_transfer_area(int width, int height,
				void (callback)(void *data), void *data)
{
	BUG_ON(callback == NULL);

	sossi.lcdc_callback = callback;
	sossi.lcdc_callback_data = data;

	clk_enable(sossi.fck);
	set_timing(WR_ACCESS);
	_set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width);
	_set_tearsync_mode(sossi.tearsync_mode, sossi.tearsync_line);
	/* CMD#/DATA */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
	set_cycles(width * height * sossi.bus_pick_width / 8);

	sossi_start_transfer();
	if (sossi.tearsync_mode) {
		/*
		 * Wait for the sync signal and start the transfer only
		 * then. We can't seem to be able to use HW sync DMA for
		 * this since LCD DMA shows huge latencies, as if it
		 * would ignore some of the DMA requests from SoSSI.
		 */
		unsigned long flags;

		spin_lock_irqsave(&sossi.lock, flags);
		sossi.vsync_dma_pending++;
		spin_unlock_irqrestore(&sossi.lock, flags);
	} else
		/* Just start the transfer right away. */
		omap_enable_lcd_dma();
}
Example #4
0
static void set_cycles(unsigned int len)
{
	unsigned long nr_cycles = len / (sossi.bus_pick_width / 8);

	BUG_ON((nr_cycles - 1) & ~0x3ffff);

	sossi_clear_bits(SOSSI_INIT1_REG, 0x3ffff);
	sossi_set_bits(SOSSI_INIT1_REG, (nr_cycles - 1) & 0x3ffff);
}
Example #5
0
static void sossi_write_data(const void *data, unsigned int len)
{
	set_timing(WR_ACCESS);
	/* CMD#/DATA */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
	set_cycles(len);
	sossi_start_transfer();
	send_data(data, len);
	sossi_stop_transfer();
	wait_end_of_write();
}
Example #6
0
static void sossi_write_data(const void *data, unsigned int len)
{
	clk_enable(sossi.fck);
	set_timing(WR_ACCESS);
	_set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width);
	/* CMD#/DATA */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
	set_cycles(len);
	sossi_start_transfer();
	send_data(data, len);
	sossi_stop_transfer();
	wait_end_of_write();
	clk_disable(sossi.fck);
}
Example #7
0
static void _set_tearsync_mode(int mode, unsigned line)
{
	u32 l;

	l = sossi_read_reg(SOSSI_TEARING_REG);
	l &= ~(((1 << 11) - 1) << 15);
	l |= line << 15;
	l &= ~(0x3 << 26);
	l |= mode << 26;
	sossi_write_reg(SOSSI_TEARING_REG, l);
	if (mode)
		sossi_set_bits(SOSSI_INIT2_REG, 1 << 6);	/* TE logic */
	else
		sossi_clear_bits(SOSSI_INIT2_REG, 1 << 6);
}
Example #8
0
static void sossi_transfer_area(int width, int height,
				void (callback)(void *data), void *data)
{
	BUG_ON(callback == NULL);

	sossi.lcdc_callback = callback;
	sossi.lcdc_callback_data = data;

	set_timing(WR_ACCESS);
	/* CMD#/DATA */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
	set_cycles(width * height * sossi.bus_pick_width / 8);

	sossi_start_transfer();
	omap_enable_lcd_dma();
}
Example #9
0
static void sossi_read_data(void *data, unsigned int len)
{
	set_timing(RD_ACCESS);
	/* CMD#/DATA */
	sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
	set_cycles(len);
	sossi_start_transfer();
	while (len >= 4) {
		*(u32 *) data = sossi_read_reg(SOSSI_FIFO_REG);
		len -= 4;
		data += 4;
	}
	while (len >= 2) {
		*(u16 *) data = sossi_read_reg16(SOSSI_FIFO_REG);
		len -= 2;
		data += 2;
	}
	while (len) {
		*(u8 *) data = sossi_read_reg8(SOSSI_FIFO_REG);
		len--;
		data++;
	}
	sossi_stop_transfer();
}