Beispiel #1
0
unsigned int exynos_dp_write_byte_to_dpcd(unsigned int reg_addr,
				unsigned char data)
{
	unsigned int reg, ret;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	writel(reg, &dp_regs->buffer_data_ctl);

	/* Select DPCD device address */
	reg = AUX_ADDR_7_0(reg_addr);
	writel(reg, &dp_regs->aux_addr_7_0);
	reg = AUX_ADDR_15_8(reg_addr);
	writel(reg, &dp_regs->aux_addr_15_8);
	reg = AUX_ADDR_19_16(reg_addr);
	writel(reg, &dp_regs->aux_addr_19_16);

	/* Write data buffer */
	reg = (unsigned int)data;
	writel(reg, &dp_regs->buf_data0);

	/*
	 * Set DisplayPort transaction and write 1 byte
	 * If bit 3 is 1, DisplayPort transaction.
	 * If Bit 3 is 0, I2C transaction.
	 */
	reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
	writel(reg, &dp_regs->aux_ch_ctl1);

	/* Start AUX transaction */
	ret = exynos_dp_start_aux_transaction();
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP Aux transaction failed\n");
		return ret;
	}

	return ret;
}
Beispiel #2
0
unsigned int exynos_dp_read_byte_from_dpcd(u32 reg_addr,
		unsigned char *data)
{
	u32 reg;
	int retval;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	lwrite32(reg, &dp_regs->buffer_data_ctl);

	/* Select DPCD device address */
	reg = AUX_ADDR_7_0(reg_addr);
	lwrite32(reg, &dp_regs->aux_addr_7_0);
	reg = AUX_ADDR_15_8(reg_addr);
	lwrite32(reg, &dp_regs->aux_addr_15_8);
	reg = AUX_ADDR_19_16(reg_addr);
	lwrite32(reg, &dp_regs->aux_addr_19_16);

	/*
	 * Set DisplayPort transaction and read 1 byte
	 * If bit 3 is 1, DisplayPort transaction.
	 * If Bit 3 is 0, I2C transaction.
	 */
	reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
	lwrite32(reg, &dp_regs->aux_ch_ctl1);

	/* Start AUX transaction */
	retval = exynos_dp_start_aux_transaction();
	if (retval != EXYNOS_DP_SUCCESS)
		printk(BIOS_DEBUG, "DP Aux Transaction fail!\n");

	/* Read data buffer */
	reg = lread32(&dp_regs->buf_data0);
	*data = (unsigned char)(reg & 0xff);

	return retval;
}
Beispiel #3
0
static int rk_edp_dpcd_transfer(struct rk_edp *edp,
				unsigned int val_addr, u8 *data,
				unsigned int length,
				enum dpcd_request request)
{
	int val;
	int i, try_times;
	int retval = 0;
	u32 len = 0;

	while (length) {
		len = MIN(length, 16);
		for (try_times = 0; try_times < 10; try_times++) {

			/* Clear AUX CH data buffer */
			val = BUF_CLR;
			write32(&edp->regs->buf_data_ctl, val);

			/* Select DPCD device address */
			val = AUX_ADDR_7_0(val_addr);
			write32(&edp->regs->aux_addr_7_0, val);
			val = AUX_ADDR_15_8(val_addr);
			write32(&edp->regs->aux_addr_15_8, val);
			val = AUX_ADDR_19_16(val_addr);
			write32(&edp->regs->aux_addr_19_16, val);

			/*
			 * Set DisplayPort transaction and read 1 byte
			 * If bit 3 is 1, DisplayPort transaction.
			 * If Bit 3 is 0, I2C transaction.
			 */
			if (request == DPCD_WRITE) {
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_WRITE;
				for (i = 0; i < len; i++)
					write32(&edp->regs->buf_data[i],
						*data++);
			} else
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_READ;

			write32(&edp->regs->aux_ch_ctl_1, val);

			/* Start AUX transaction */
			retval = rk_edp_start_aux_transaction(edp);
			if (retval == 0)
				break;
			else
				printk(BIOS_WARNING, "read dpcd Aux Transaction fail!\n");

		}

		if (retval)
			return -1;

		if (request == DPCD_READ) {
			for (i = 0; i < len; i++)
				*data++ = (u8)read32(&edp->regs->buf_data[i]);
		}

		length -= len;
		val_addr += 16;
	}
	return 0;
}
Beispiel #4
0
static int rk_edp_dpcd_transfer(struct rk3288_edp *regs,
				unsigned int val_addr, u8 *in_data,
				unsigned int length,
				enum dpcd_request request)
{
	int val;
	int i, try_times;
	u8 *data;
	int ret = 0;
	u32 len = 0;

	while (length) {
		len = min(length, 16U);
		for (try_times = 0; try_times < 10; try_times++) {
			data = in_data;
			/* Clear AUX CH data buffer */
			writel(BUF_CLR, &regs->buf_data_ctl);

			/* Select DPCD device address */
			writel(AUX_ADDR_7_0(val_addr), &regs->aux_addr_7_0);
			writel(AUX_ADDR_15_8(val_addr), &regs->aux_addr_15_8);
			writel(AUX_ADDR_19_16(val_addr), &regs->aux_addr_19_16);

			/*
			 * Set DisplayPort transaction and read 1 byte
			 * If bit 3 is 1, DisplayPort transaction.
			 * If Bit 3 is 0, I2C transaction.
			 */
			if (request == DPCD_WRITE) {
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_WRITE;
				for (i = 0; i < len; i++)
					writel(*data++, &regs->buf_data[i]);
			} else
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_READ;

			writel(val, &regs->aux_ch_ctl_1);

			/* Start AUX transaction */
			ret = rk_edp_start_aux_transaction(regs);
			if (ret == 0)
				break;
			else
				printf("read dpcd Aux Transaction fail!\n");
		}

		if (ret)
			return ret;

		if (request == DPCD_READ) {
			for (i = 0; i < len; i++)
				*data++ = (u8)readl(&regs->buf_data[i]);
		}

		length -= len;
		val_addr += len;
		in_data += len;
	}

	return 0;
}
Beispiel #5
0
unsigned int exynos_dp_read_bytes_from_dpcd(u32 reg_addr,
				unsigned int count,
				unsigned char data[])
{
	u32 reg;
	unsigned int start_offset;
	unsigned int cur_data_count;
	unsigned int cur_data_idx;
	unsigned int retry_cnt;
	unsigned int ret = 0;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	lwrite32(reg, &dp_regs->buffer_data_ctl);

	start_offset = 0;
	while (start_offset < count) {
		/* Buffer size of AUX CH is 16 * 4bytes */
		if ((count - start_offset) > 16)
			cur_data_count = 16;
		else
			cur_data_count = count - start_offset;

		retry_cnt = 5;
		while (retry_cnt) {
			/* Select DPCD device address */
			reg = AUX_ADDR_7_0(reg_addr + start_offset);
			lwrite32(reg, &dp_regs->aux_addr_7_0);
			reg = AUX_ADDR_15_8(reg_addr + start_offset);
			lwrite32(reg, &dp_regs->aux_addr_15_8);
			reg = AUX_ADDR_19_16(reg_addr + start_offset);
			lwrite32(reg, &dp_regs->aux_addr_19_16);
			/*
			 * Set DisplayPort transaction and read
			 * If bit 3 is 1, DisplayPort transaction.
			 * If Bit 3 is 0, I2C transaction.
			 */
			reg = AUX_LENGTH(cur_data_count) |
				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
			lwrite32(reg, &dp_regs->aux_ch_ctl1);

			/* Start AUX transaction */
			ret = exynos_dp_start_aux_transaction();
			if (ret != EXYNOS_DP_SUCCESS) {
				if (retry_cnt == 0) {
					printk(BIOS_ERR, "DP Aux Transaction failed\n");
					return ret;
				}
				retry_cnt--;
			} else
				break;
		}

		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
				cur_data_idx++) {
			reg = lread32((void *)((u32)&dp_regs->buf_data0 +
					      4 * cur_data_idx));
			data[start_offset + cur_data_idx] = (unsigned char)reg;
		}

		start_offset += cur_data_count;
	}

	return ret;
}