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

Commit 0c90fa42 authored by Xiaoming Zhou's avatar Xiaoming Zhou
Browse files

msm: mdss: abstract the dsi command utility API



The dsi command parsing and construction functionalities
are hardware independent.  This is to abstract these
utility API, so that it can be shared with different versions
of  dsi host controllers.

Change-Id: I8481d9fd21e5eacc4542c72c064fa37d7fd3a11b
Signed-off-by: default avatarXiaoming Zhou <zhoux@codeaurora.org>
parent b8a2a10e
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -19,7 +19,7 @@ endif
dsi-v2-objs = dsi_v2.o dsi_host_v2.o dsi_io_v2.o
dsi-v2-objs = dsi_v2.o dsi_host_v2.o dsi_io_v2.o
obj-$(CONFIG_FB_MSM_MDSS) += dsi-v2.o
obj-$(CONFIG_FB_MSM_MDSS) += dsi-v2.o


mdss-dsi-objs := mdss_dsi.o mdss_dsi_host.o
mdss-dsi-objs := mdss_dsi.o mdss_dsi_host.o mdss_dsi_cmd.o
mdss-dsi-objs += mdss_dsi_panel.o
mdss-dsi-objs += mdss_dsi_panel.o
mdss-dsi-objs += msm_mdss_io_8974.o
mdss-dsi-objs += msm_mdss_io_8974.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss-dsi.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss-dsi.o
+2 −108
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@


#include "mdss_panel.h"
#include "mdss_panel.h"
#include "mdss_io_util.h"
#include "mdss_io_util.h"
#include "mdss_dsi_cmd.h"


#define MMSS_SERDES_BASE_PHY 0x04f01000 /* mmss (De)Serializer CFG */
#define MMSS_SERDES_BASE_PHY 0x04f01000 /* mmss (De)Serializer CFG */


@@ -194,81 +195,6 @@ struct dsi_clk_desc {
	u32 pre_div_func;
	u32 pre_div_func;
};
};


#define DSI_HOST_HDR_SIZE	4
#define DSI_HDR_LAST		BIT(31)
#define DSI_HDR_LONG_PKT	BIT(30)
#define DSI_HDR_BTA		BIT(29)
#define DSI_HDR_VC(vc)		(((vc) & 0x03) << 22)
#define DSI_HDR_DTYPE(dtype)	(((dtype) & 0x03f) << 16)
#define DSI_HDR_DATA2(data)	(((data) & 0x0ff) << 8)
#define DSI_HDR_DATA1(data)	((data) & 0x0ff)
#define DSI_HDR_WC(wc)		((wc) & 0x0ffff)

#define MDSS_DSI_MRPS	0x04  /* Maximum Return Packet Size */

#define MDSS_DSI_LEN 8 /* 4 x 4 - 6 - 2, bytes dcs header+crc-align  */

struct dsi_buf {
	u32 *hdr;	/* dsi host header */
	char *start;	/* buffer start addr */
	char *end;	/* buffer end addr */
	int size;	/* size of buffer */
	char *data;	/* buffer */
	int len;	/* data length */
	dma_addr_t dmap; /* mapped dma addr */
};

/* dcs read/write */
#define DTYPE_DCS_WRITE		0x05	/* short write, 0 parameter */
#define DTYPE_DCS_WRITE1	0x15	/* short write, 1 parameter */
#define DTYPE_DCS_READ		0x06	/* read */
#define DTYPE_DCS_LWRITE	0x39	/* long write */

/* generic read/write */
#define DTYPE_GEN_WRITE		0x03	/* short write, 0 parameter */
#define DTYPE_GEN_WRITE1	0x13	/* short write, 1 parameter */
#define DTYPE_GEN_WRITE2	0x23	/* short write, 2 parameter */
#define DTYPE_GEN_LWRITE	0x29	/* long write */
#define DTYPE_GEN_READ		0x04	/* long read, 0 parameter */
#define DTYPE_GEN_READ1		0x14	/* long read, 1 parameter */
#define DTYPE_GEN_READ2		0x24	/* long read, 2 parameter */

#define DTYPE_TEAR_ON		0x35	/* set tear on */
#define DTYPE_MAX_PKTSIZE	0x37	/* set max packet size */
#define DTYPE_NULL_PKT		0x09	/* null packet, no data */
#define DTYPE_BLANK_PKT		0x19	/* blankiing packet, no data */

#define DTYPE_CM_ON		0x02	/* color mode off */
#define DTYPE_CM_OFF		0x12	/* color mode on */
#define DTYPE_PERIPHERAL_OFF	0x22
#define DTYPE_PERIPHERAL_ON	0x32

/*
 * dcs response
 */
#define DTYPE_ACK_ERR_RESP      0x02
#define DTYPE_EOT_RESP          0x08    /* end of tx */
#define DTYPE_GEN_READ1_RESP    0x11    /* 1 parameter, short */
#define DTYPE_GEN_READ2_RESP    0x12    /* 2 parameter, short */
#define DTYPE_GEN_LREAD_RESP    0x1a
#define DTYPE_DCS_LREAD_RESP    0x1c
#define DTYPE_DCS_READ1_RESP    0x21    /* 1 parameter, short */
#define DTYPE_DCS_READ2_RESP    0x22    /* 2 parameter, short */


struct dsi_ctrl_hdr {
	char dtype;	/* data type */
	char last;	/* last in chain */
	char vc;	/* virtual chan */
	char ack;	/* ask ACK from peripheral */
	char wait;	/* ms */
	short dlen;	/* 16 bits */
} __packed;

struct dsi_cmd_desc {
	struct dsi_ctrl_hdr dchdr;
	char *payload;
};


struct dsi_panel_cmds {
struct dsi_panel_cmds {
	char *buf;
	char *buf;
@@ -278,29 +204,6 @@ struct dsi_panel_cmds {
	int link_state;
	int link_state;
};
};


#define CMD_REQ_MAX     4

#define CMD_REQ_RX      0x0001
#define CMD_REQ_COMMIT  0x0002
#define CMD_CLK_CTRL    0x0004
#define CMD_REQ_NO_MAX_PKT_SIZE 0x0008

struct dcs_cmd_req {
	struct dsi_cmd_desc *cmds;
	int cmds_cnt;
	u32 flags;
	int rlen;       /* rx length */
	char *rbuf;	/* rx buf */
	void (*cb)(int data);
};

struct dcs_cmd_list {
	int put;
	int get;
	int tot;
	struct dcs_cmd_req list[CMD_REQ_MAX];
};

struct dsi_kickoff_action {
struct dsi_kickoff_action {
	struct list_head act_entry;
	struct list_head act_entry;
	void (*action) (void *);
	void (*action) (void *);
@@ -330,6 +233,7 @@ struct mdss_dsi_ctrl_pdata {
	int (*off) (struct mdss_panel_data *pdata);
	int (*off) (struct mdss_panel_data *pdata);
	int (*partial_update_fnc) (struct mdss_panel_data *pdata);
	int (*partial_update_fnc) (struct mdss_panel_data *pdata);
	int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
	int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
	void (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
	struct mdss_panel_data panel_data;
	struct mdss_panel_data panel_data;
	unsigned char *ctrl_base;
	unsigned char *ctrl_base;
	int reg_size;
	int reg_size;
@@ -391,11 +295,6 @@ struct mdss_dsi_ctrl_pdata {
int dsi_panel_device_register(struct device_node *pan_node,
int dsi_panel_device_register(struct device_node *pan_node,
				struct mdss_dsi_ctrl_pdata *ctrl_pdata);
				struct mdss_dsi_ctrl_pdata *ctrl_pdata);


char *mdss_dsi_buf_reserve_hdr(struct dsi_buf *dp, int hlen);
char *mdss_dsi_buf_init(struct dsi_buf *dp);
void mdss_dsi_init(void);
int mdss_dsi_buf_alloc(struct dsi_buf *, int size);
int mdss_dsi_cmd_dma_add(struct dsi_buf *dp, struct dsi_cmd_desc *cm);
int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
		struct dsi_cmd_desc *cmds, int cnt);
		struct dsi_cmd_desc *cmds, int cnt);


@@ -404,8 +303,6 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,


void mdss_dsi_host_init(struct mipi_panel_info *pinfo,
void mdss_dsi_host_init(struct mipi_panel_info *pinfo,
				struct mdss_panel_data *pdata);
				struct mdss_panel_data *pdata);
void mdss_dsi_set_tear_on(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_set_tear_off(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_op_mode_config(int mode,
void mdss_dsi_op_mode_config(int mode,
				struct mdss_panel_data *pdata);
				struct mdss_panel_data *pdata);
void mdss_dsi_cmd_mode_ctrl(int enable);
void mdss_dsi_cmd_mode_ctrl(int enable);
@@ -442,9 +339,6 @@ void mdss_dsi_ctrl_init(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
int mdss_dsi_cmdlist_put(struct mdss_dsi_ctrl_pdata *ctrl,
				struct dcs_cmd_req *cmdreq);
struct dcs_cmd_req *mdss_dsi_cmdlist_get(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmdlist_kickoff(int intf);
void mdss_dsi_cmdlist_kickoff(int intf);
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);


+689 −0
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/iopoll.h>
#include <linux/kthread.h>

#include <mach/iommu_domains.h>

#include "mdss_dsi_cmd.h"
#include "mdss_dsi.h"

/*
 * mipi dsi buf mechanism
 */
char *mdss_dsi_buf_reserve(struct dsi_buf *dp, int len)
{
	dp->data += len;
	return dp->data;
}

char *mdss_dsi_buf_unreserve(struct dsi_buf *dp, int len)
{
	dp->data -= len;
	return dp->data;
}

char *mdss_dsi_buf_push(struct dsi_buf *dp, int len)
{
	dp->data -= len;
	dp->len += len;
	return dp->data;
}

char *mdss_dsi_buf_reserve_hdr(struct dsi_buf *dp, int hlen)
{
	dp->hdr = (u32 *)dp->data;
	return mdss_dsi_buf_reserve(dp, hlen);
}

char *mdss_dsi_buf_init(struct dsi_buf *dp)
{
	int off;

	dp->data = dp->start;
	off = (int)dp->data;
	/* 8 byte align */
	off &= 0x07;
	if (off)
		off = 8 - off;
	dp->data += off;
	dp->len = 0;
	return dp->data;
}

int mdss_dsi_buf_alloc(struct dsi_buf *dp, int size)
{

	dp->start = dma_alloc_writecombine(NULL, size, &dp->dmap, GFP_KERNEL);
	if (dp->start == NULL) {
		pr_err("%s:%u\n", __func__, __LINE__);
		return -ENOMEM;
	}

	dp->end = dp->start + size;
	dp->size = size;

	if ((int)dp->start & 0x07)
		pr_err("%s: buf NOT 8 bytes aligned\n", __func__);

	dp->data = dp->start;
	dp->len = 0;
	return size;
}

/*
 * mipi dsi generic long write
 */
static int mdss_dsi_generic_lwrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	char *bp;
	u32 *hp;
	int i, len = 0;

	dchdr = &cm->dchdr;
	bp = mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);

	/* fill up payload */
	if (cm->payload) {
		len = dchdr->dlen;
		len += 3;
		len &= ~0x03;	/* multipled by 4 */
		for (i = 0; i < dchdr->dlen; i++)
			*bp++ = cm->payload[i];

		/* append 0xff to the end */
		for (; i < len; i++)
			*bp++ = 0xff;

		dp->len += len;
	}

	/* fill up header */
	hp = dp->hdr;
	*hp = 0;
	*hp = DSI_HDR_WC(dchdr->dlen);
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_LONG_PKT;
	*hp |= DSI_HDR_DTYPE(DTYPE_GEN_LWRITE);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	len += DSI_HOST_HDR_SIZE;

	return len;
}

/*
 * mipi dsi generic short write with 0, 1 2 parameters
 */
static int mdss_dsi_generic_swrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;
	int len;

	dchdr = &cm->dchdr;
	if (dchdr->dlen && cm->payload == 0) {
		pr_err("%s: NO payload error\n", __func__);
		return 0;
	}

	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;


	len = (dchdr->dlen > 2) ? 2 : dchdr->dlen;

	if (len == 1) {
		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE1);
		*hp |= DSI_HDR_DATA1(cm->payload[0]);
		*hp |= DSI_HDR_DATA2(0);
	} else if (len == 2) {
		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE2);
		*hp |= DSI_HDR_DATA1(cm->payload[0]);
		*hp |= DSI_HDR_DATA2(cm->payload[1]);
	} else {
		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE);
		*hp |= DSI_HDR_DATA1(0);
		*hp |= DSI_HDR_DATA2(0);
	}

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

/*
 * mipi dsi gerneric read with 0, 1 2 parameters
 */
static int mdss_dsi_generic_read(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;
	int len;

	dchdr = &cm->dchdr;
	if (dchdr->dlen && cm->payload == 0) {
		pr_err("%s: NO payload error\n", __func__);
		return 0;
	}

	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_BTA;
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	len = (dchdr->dlen > 2) ? 2 : dchdr->dlen;

	if (len == 1) {
		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ1);
		*hp |= DSI_HDR_DATA1(cm->payload[0]);
		*hp |= DSI_HDR_DATA2(0);
	} else if (len == 2) {
		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ2);
		*hp |= DSI_HDR_DATA1(cm->payload[0]);
		*hp |= DSI_HDR_DATA2(cm->payload[1]);
	} else {
		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ);
		*hp |= DSI_HDR_DATA1(0);
		*hp |= DSI_HDR_DATA2(0);
	}

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

/*
 * mipi dsi dcs long write
 */
static int mdss_dsi_dcs_lwrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	char *bp;
	u32 *hp;
	int i, len = 0;

	dchdr = &cm->dchdr;
	bp = mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);

	/*
	 * fill up payload
	 * dcs command byte (first byte) followed by payload
	 */
	if (cm->payload) {
		len = dchdr->dlen;
		len += 3;
		len &= ~0x03;	/* multipled by 4 */
		for (i = 0; i < dchdr->dlen; i++)
			*bp++ = cm->payload[i];

		/* append 0xff to the end */
		for (; i < len; i++)
			*bp++ = 0xff;

		dp->len += len;
	}

	/* fill up header */
	hp = dp->hdr;
	*hp = 0;
	*hp = DSI_HDR_WC(dchdr->dlen);
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_LONG_PKT;
	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_LWRITE);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);

	len += DSI_HOST_HDR_SIZE;
	return len;
}

/*
 * mipi dsi dcs short write with 0 parameters
 */
static int mdss_dsi_dcs_swrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;
	int len;

	dchdr = &cm->dchdr;
	if (cm->payload == 0) {
		pr_err("%s: NO payload error\n", __func__);
		return -EINVAL;
	}

	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	if (dchdr->ack)		/* ask ACK trigger msg from peripeheral */
		*hp |= DSI_HDR_BTA;
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	len = (dchdr->dlen > 1) ? 1 : dchdr->dlen;

	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_WRITE);
	*hp |= DSI_HDR_DATA1(cm->payload[0]);	/* dcs command byte */
	*hp |= DSI_HDR_DATA2(0);

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

/*
 * mipi dsi dcs short write with 1 parameters
 */
static int mdss_dsi_dcs_swrite1(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	if (dchdr->dlen < 2 || cm->payload == 0) {
		pr_err("%s: NO payload error\n", __func__);
		return -EINVAL;
	}

	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	if (dchdr->ack)		/* ask ACK trigger msg from peripeheral */
		*hp |= DSI_HDR_BTA;
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_WRITE1);
	*hp |= DSI_HDR_DATA1(cm->payload[0]);	/* dcs comamnd byte */
	*hp |= DSI_HDR_DATA2(cm->payload[1]);	/* parameter */

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}
/*
 * mipi dsi dcs read with 0 parameters
 */

static int mdss_dsi_dcs_read(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	if (cm->payload == 0) {
		pr_err("%s: NO payload error\n", __func__);
		return -EINVAL;
	}

	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_BTA;
	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_READ);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	*hp |= DSI_HDR_DATA1(cm->payload[0]);	/* dcs command byte */
	*hp |= DSI_HDR_DATA2(0);

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_cm_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_CM_ON);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_cm_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_CM_OFF);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_peripheral_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_PERIPHERAL_ON);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_peripheral_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_PERIPHERAL_OFF);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_set_max_pktsize(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	if (cm->payload == 0) {
		pr_err("%s: NO payload error\n", __func__);
		return 0;
	}

	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_MAX_PKTSIZE);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	*hp |= DSI_HDR_DATA1(cm->payload[0]);
	*hp |= DSI_HDR_DATA2(cm->payload[1]);

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_null_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp = DSI_HDR_WC(dchdr->dlen);
	*hp |= DSI_HDR_LONG_PKT;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_NULL_PKT);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

static int mdss_dsi_blank_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	u32 *hp;

	dchdr = &cm->dchdr;
	mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
	hp = dp->hdr;
	*hp = 0;
	*hp = DSI_HDR_WC(dchdr->dlen);
	*hp |= DSI_HDR_LONG_PKT;
	*hp |= DSI_HDR_VC(dchdr->vc);
	*hp |= DSI_HDR_DTYPE(DTYPE_BLANK_PKT);
	if (dchdr->last)
		*hp |= DSI_HDR_LAST;

	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
	return DSI_HOST_HDR_SIZE; /* 4 bytes */
}

/*
 * prepare cmd buffer to be txed
 */
int mdss_dsi_cmd_dma_add(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
{
	struct dsi_ctrl_hdr *dchdr;
	int len = 0;

	dchdr = &cm->dchdr;

	switch (dchdr->dtype) {
	case DTYPE_GEN_WRITE:
	case DTYPE_GEN_WRITE1:
	case DTYPE_GEN_WRITE2:
		len = mdss_dsi_generic_swrite(dp, cm);
		break;
	case DTYPE_GEN_LWRITE:
		len = mdss_dsi_generic_lwrite(dp, cm);
		break;
	case DTYPE_GEN_READ:
	case DTYPE_GEN_READ1:
	case DTYPE_GEN_READ2:
		len = mdss_dsi_generic_read(dp, cm);
		break;
	case DTYPE_DCS_LWRITE:
		len = mdss_dsi_dcs_lwrite(dp, cm);
		break;
	case DTYPE_DCS_WRITE:
		len = mdss_dsi_dcs_swrite(dp, cm);
		break;
	case DTYPE_DCS_WRITE1:
		len = mdss_dsi_dcs_swrite1(dp, cm);
		break;
	case DTYPE_DCS_READ:
		len = mdss_dsi_dcs_read(dp, cm);
		break;
	case DTYPE_MAX_PKTSIZE:
		len = mdss_dsi_set_max_pktsize(dp, cm);
		break;
	case DTYPE_NULL_PKT:
		len = mdss_dsi_null_pkt(dp, cm);
		break;
	case DTYPE_BLANK_PKT:
		len = mdss_dsi_blank_pkt(dp, cm);
		break;
	case DTYPE_CM_ON:
		len = mdss_dsi_cm_on(dp, cm);
		break;
	case DTYPE_CM_OFF:
		len = mdss_dsi_cm_off(dp, cm);
		break;
	case DTYPE_PERIPHERAL_ON:
		len = mdss_dsi_peripheral_on(dp, cm);
		break;
	case DTYPE_PERIPHERAL_OFF:
		len = mdss_dsi_peripheral_off(dp, cm);
		break;
	default:
		pr_debug("%s: dtype=%x NOT supported\n",
					__func__, dchdr->dtype);
		break;

	}

	return len;
}

/*
 * mdss_dsi_short_read1_resp: 1 parameter
 */
int mdss_dsi_short_read1_resp(struct dsi_buf *rp)
{
	/* strip out dcs type */
	rp->data++;
	rp->len = 1;
	return rp->len;
}

/*
 * mdss_dsi_short_read2_resp: 2 parameter
 */
int mdss_dsi_short_read2_resp(struct dsi_buf *rp)
{
	/* strip out dcs type */
	rp->data++;
	rp->len = 2;
	return rp->len;
}

int mdss_dsi_long_read_resp(struct dsi_buf *rp)
{
	/* strip out dcs header */
	rp->data += 4;
	rp->len -= 4;
	return rp->len;
}

static char set_tear_on[2] = {0x35, 0x00};
static struct dsi_cmd_desc dsi_tear_on_cmd = {
	{DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_tear_on)}, set_tear_on};

static char set_tear_off[2] = {0x34, 0x00};
static struct dsi_cmd_desc dsi_tear_off_cmd = {
	{DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(set_tear_off)}, set_tear_off};

void mdss_dsi_set_tear_on(struct mdss_dsi_ctrl_pdata *ctrl)
{
	struct dcs_cmd_req cmdreq;

	cmdreq.cmds = &dsi_tear_on_cmd;
	cmdreq.cmds_cnt = 1;
	cmdreq.flags = CMD_REQ_COMMIT;
	cmdreq.rlen = 0;
	cmdreq.cb = NULL;

	mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}

void mdss_dsi_set_tear_off(struct mdss_dsi_ctrl_pdata *ctrl)
{
	struct dcs_cmd_req cmdreq;

	cmdreq.cmds = &dsi_tear_off_cmd;
	cmdreq.cmds_cnt = 1;
	cmdreq.flags = CMD_REQ_COMMIT;
	cmdreq.rlen = 0;
	cmdreq.cb = NULL;

	mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}

/*
 * mdss_dsi_cmd_get: ctrl->cmd_mutex acquired by caller
 */
struct dcs_cmd_req *mdss_dsi_cmdlist_get(struct mdss_dsi_ctrl_pdata *ctrl)
{
	struct dcs_cmd_list *clist;
	struct dcs_cmd_req *req = NULL;

	clist = &ctrl->cmdlist;
	if (clist->get != clist->put) {
		req = &clist->list[clist->get];
		clist->get++;
		clist->get %= CMD_REQ_MAX;
		clist->tot--;
		pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
		clist->tot, clist->put, clist->get);
	}
	return req;
}

int mdss_dsi_cmdlist_put(struct mdss_dsi_ctrl_pdata *ctrl,
				struct dcs_cmd_req *cmdreq)
{
	struct dcs_cmd_req *req;
	struct dcs_cmd_list *clist;
	int ret = 0;

	mutex_lock(&ctrl->cmd_mutex);
	clist = &ctrl->cmdlist;
	req = &clist->list[clist->put];
	*req = *cmdreq;
	clist->put++;
	clist->put %= CMD_REQ_MAX;
	clist->tot++;
	if (clist->put == clist->get) {
		/* drop the oldest one */
		pr_debug("%s: DROP, tot=%d put=%d get=%d\n", __func__,
			clist->tot, clist->put, clist->get);
		clist->get++;
		clist->get %= CMD_REQ_MAX;
		clist->tot--;
	}
	mutex_unlock(&ctrl->cmd_mutex);

	ret++;
	pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
		clist->tot, clist->put, clist->get);

	if (req->flags & CMD_REQ_COMMIT) {
		if (!ctrl->cmdlist_commit)
			pr_err("cmdlist_commit not implemented!\n");
		else
			ctrl->cmdlist_commit(ctrl, 0);
	}
	return ret;
}
+133 −0

File added.

Preview size limit exceeded, changes collapsed.

+1 −660

File changed.

Preview size limit exceeded, changes collapsed.