summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-11 11:35:20 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-11 11:35:20 -0700
commitae7908ba2269cc465298a001385f0d37949b1ad3 (patch)
tree1cebe173971800ed94879ea66e5fdf0177ecc442
parentebe54d193f0c3377bd2e2fd6d990e498919be5cc (diff)
parentc5a71f2da3297ee886f375550e274a12f26615ec (diff)
Merge "msm: mdss: displayport: replace delayed work with work"
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c22
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c118
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c39
4 files changed, 105 insertions, 76 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 72b262e8171a..4e68952d33a9 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1022,6 +1022,8 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic)
pinfo->lcdc.hsync_skew = 0;
pinfo->is_pluggable = true;
+ dp_drv->bpp = pinfo->bpp;
+
pr_debug("update res. vic= %d, pclk_rate = %llu\n",
dp_drv->vic, pinfo->clk_rate);
@@ -1786,16 +1788,15 @@ static void mdss_dp_do_link_train(struct mdss_dp_drv_pdata *dp)
static void mdss_dp_event_work(struct work_struct *work)
{
struct mdss_dp_drv_pdata *dp = NULL;
- struct delayed_work *dw = to_delayed_work(work);
unsigned long flag;
- u32 todo = 0, dp_config_pkt[2];
+ u32 todo = 0, config;
- if (!dw) {
+ if (!work) {
pr_err("invalid work structure\n");
return;
}
- dp = container_of(dw, struct mdss_dp_drv_pdata, dwork);
+ dp = container_of(work, struct mdss_dp_drv_pdata, work);
spin_lock_irqsave(&dp->event_lock, flag);
todo = dp->current_event;
@@ -1840,11 +1841,9 @@ static void mdss_dp_event_work(struct work_struct *work)
SVDM_CMD_TYPE_INITIATOR, 0x1, 0x0, 0x0);
break;
case EV_USBPD_DP_CONFIGURE:
- dp_config_pkt[0] = SVDM_HDR(USB_C_DP_SID, VDM_VERSION, 0x1,
- SVDM_CMD_TYPE_INITIATOR, DP_VDM_CONFIGURE);
- dp_config_pkt[1] = mdss_dp_usbpd_gen_config_pkt(dp);
+ config = mdss_dp_usbpd_gen_config_pkt(dp);
usbpd_send_svdm(dp->pd, USB_C_DP_SID, DP_VDM_CONFIGURE,
- SVDM_CMD_TYPE_INITIATOR, 0x1, dp_config_pkt, 0x2);
+ SVDM_CMD_TYPE_INITIATOR, 0x1, &config, 0x1);
break;
default:
pr_err("Unknown event:%d\n", todo);
@@ -1855,7 +1854,7 @@ static void dp_send_events(struct mdss_dp_drv_pdata *dp, u32 events)
{
spin_lock(&dp->event_lock);
dp->current_event = events;
- queue_delayed_work(dp->workq, &dp->dwork, HZ / 100);
+ queue_work(dp->workq, &dp->work);
spin_unlock(&dp->event_lock);
}
@@ -1931,7 +1930,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp)
return -EPERM;
}
- INIT_DELAYED_WORK(&dp->dwork, mdss_dp_event_work);
+ INIT_WORK(&dp->work, mdss_dp_event_work);
return 0;
}
@@ -2050,8 +2049,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
}
break;
case DP_VDM_CONFIGURE:
- if ((dp_drv->cable_connected == true)
- || (cmd_type == SVDM_CMD_TYPE_RESP_ACK)) {
+ if (cmd_type == SVDM_CMD_TYPE_RESP_ACK) {
dp_drv->alt_mode.current_state = DP_CONFIGURE_DONE;
pr_debug("config USBPD to DP done\n");
mdss_dp_host_init(&dp_drv->panel_data);
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index ddadb7b6709c..6c391f6f7de0 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -428,7 +428,7 @@ struct mdss_dp_drv_pdata {
/* event */
struct workqueue_struct *workq;
- struct delayed_work dwork;
+ struct work_struct work;
u32 current_event;
spinlock_t event_lock;
spinlock_t lock;
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index f1a63dc68442..119e2a2b05cf 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -374,7 +374,19 @@ static int dp_aux_read_buf(struct mdss_dp_drv_pdata *ep, u32 addr,
/*
* edid standard header bytes
*/
-static char edid_hdr[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
+static u8 edid_hdr[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
+
+static bool dp_edid_is_valid_header(u8 *buf)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(edid_hdr); i++) {
+ if (buf[i] != edid_hdr[i])
+ return false;
+ }
+
+ return true;
+}
int dp_edid_buf_error(char *buf, int len)
{
@@ -396,11 +408,6 @@ int dp_edid_buf_error(char *buf, int len)
return -EINVAL;
}
- if (strncmp(buf, edid_hdr, strlen(edid_hdr))) {
- pr_err("Error: header\n");
- return -EINVAL;
- }
-
return 0;
}
@@ -708,10 +715,11 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep)
int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
{
- struct edp_buf *rp;
- int cnt, rlen;
- int ret = 0;
- int blk_num = 0;
+ struct edp_buf *rp = &dp->rxp;
+ int rlen, ret = 0;
+ int edid_blk = 0, blk_num = 0, retries = 10;
+ bool edid_parsing_done = false;
+ const u8 cea_tag = 0x02;
ret = dp_aux_chan_ready(dp);
if (ret) {
@@ -719,70 +727,56 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
return ret;
}
- for (cnt = 5; cnt; cnt--) {
- rlen = dp_aux_read_buf
- (dp, EDID_START_ADDRESS, EDID_BLOCK_SIZE, 1);
- if (rlen > 0) {
- pr_debug("cnt=%d, block=%d, rlen=%d\n",
- cnt, blk_num, rlen);
-
- rp = &dp->rxp;
- if (!dp_edid_buf_error(rp->data, rp->len))
- break;
+ do {
+ rlen = dp_aux_read_buf(dp, EDID_START_ADDRESS +
+ (blk_num * EDID_BLOCK_SIZE),
+ EDID_BLOCK_SIZE, 1);
+ if (rlen != EDID_BLOCK_SIZE) {
+ pr_err("Read failed. rlen=%d\n", rlen);
+ continue;
}
- }
- if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) {
- pr_err("Read failed. rlen=%d\n", rlen);
- return -EINVAL;
- }
+ pr_debug("blk_num=%d, rlen=%d\n", blk_num, rlen);
- rp = &dp->rxp;
+ if (dp_edid_is_valid_header(rp->data)) {
+ if (dp_edid_buf_error(rp->data, rp->len))
+ continue;
- dp_extract_edid_manufacturer(&dp->edid, rp->data);
- dp_extract_edid_product(&dp->edid, rp->data);
- dp_extract_edid_version(&dp->edid, rp->data);
- dp_extract_edid_ext_block_cnt(&dp->edid, rp->data);
- dp_extract_edid_video_support(&dp->edid, rp->data);
- dp_extract_edid_feature(&dp->edid, rp->data);
- dp_extract_edid_detailed_timing_description(&dp->edid, rp->data);
- /* for the first block initialize the edid buffer size */
- dp->edid_buf_size = 0;
+ if (edid_parsing_done) {
+ blk_num++;
+ continue;
+ }
- pr_debug("edid extension = %d\n",
- dp->edid.ext_block_cnt);
+ dp_extract_edid_manufacturer(&dp->edid, rp->data);
+ dp_extract_edid_product(&dp->edid, rp->data);
+ dp_extract_edid_version(&dp->edid, rp->data);
+ dp_extract_edid_ext_block_cnt(&dp->edid, rp->data);
+ dp_extract_edid_video_support(&dp->edid, rp->data);
+ dp_extract_edid_feature(&dp->edid, rp->data);
+ dp_extract_edid_detailed_timing_description(&dp->edid,
+ rp->data);
- memcpy(dp->edid_buf, rp->data, EDID_BLOCK_SIZE);
- dp->edid_buf_size += EDID_BLOCK_SIZE;
+ edid_parsing_done = true;
+ } else {
+ edid_blk++;
+ blk_num++;
- if (!dp->edid.ext_block_cnt)
- return 0;
+ /* fix dongle byte shift issue */
+ if (edid_blk == 1 && rp->data[0] != cea_tag) {
+ u8 tmp[EDID_BLOCK_SIZE - 1];
- for (blk_num = 1; blk_num <= dp->edid.ext_block_cnt;
- blk_num++) {
- for (cnt = 5; cnt; cnt--) {
- rlen = dp_aux_read_buf
- (dp, EDID_START_ADDRESS +
- (blk_num * EDID_BLOCK_SIZE),
- EDID_BLOCK_SIZE, 1);
- if (rlen > 0) {
- pr_debug("cnt=%d, blk_num=%d, rlen=%d\n",
- cnt, blk_num, rlen);
- rp = &dp->rxp;
- if (!dp_edid_buf_error(rp->data, rp->len))
- break;
+ memcpy(tmp, rp->data, EDID_BLOCK_SIZE - 1);
+ rp->data[0] = cea_tag;
+ memcpy(rp->data + 1, tmp, EDID_BLOCK_SIZE - 1);
}
}
- if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) {
- pr_err("Read failed. rlen=%d\n", rlen);
- return -EINVAL;
- }
+ memcpy(dp->edid_buf + (edid_blk * EDID_BLOCK_SIZE),
+ rp->data, EDID_BLOCK_SIZE);
- memcpy(dp->edid_buf + (blk_num * EDID_BLOCK_SIZE),
- rp->data, EDID_BLOCK_SIZE);
- dp->edid_buf_size += EDID_BLOCK_SIZE;
- }
+ if (edid_blk == dp->edid.ext_block_cnt)
+ return 0;
+ } while (retries--);
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index f1245a024a88..92acb910e0c3 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -32,6 +32,29 @@
#define AUDIO_FREQ_48 48000
#define DP_AUDIO_FREQ_COUNT 3
+enum mdss_dp_pin_assignment {
+ PIN_ASSIGNMENT_A,
+ PIN_ASSIGNMENT_B,
+ PIN_ASSIGNMENT_C,
+ PIN_ASSIGNMENT_D,
+ PIN_ASSIGNMENT_E,
+ PIN_ASSIGNMENT_F,
+ PIN_ASSIGNMENT_MAX,
+};
+
+static const char *mdss_dp_pin_name(u8 pin)
+{
+ switch (pin) {
+ case PIN_ASSIGNMENT_A: return "PIN_ASSIGNMENT_A";
+ case PIN_ASSIGNMENT_B: return "PIN_ASSIGNMENT_B";
+ case PIN_ASSIGNMENT_C: return "PIN_ASSIGNMENT_C";
+ case PIN_ASSIGNMENT_D: return "PIN_ASSIGNMENT_D";
+ case PIN_ASSIGNMENT_E: return "PIN_ASSIGNMENT_E";
+ case PIN_ASSIGNMENT_F: return "PIN_ASSIGNMENT_F";
+ default: return "UNKNOWN";
+ }
+}
+
static const uint32_t naud_value[DP_AUDIO_FREQ_COUNT][DP_AUDIO_FREQ_COUNT] = {
{ 10125, 16875, 33750 },
{ 5625, 9375, 18750 },
@@ -477,9 +500,23 @@ void mdss_dp_usbpd_ext_dp_status(struct usbpd_dp_status *dp_status)
u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp)
{
+ u8 pin_cfg, pin;
u32 config = 0;
- config |= (dp->alt_mode.dp_cap.dlink_pin_config << 8);
+ pin_cfg = dp->alt_mode.dp_cap.dlink_pin_config;
+
+ for (pin = PIN_ASSIGNMENT_A; pin < PIN_ASSIGNMENT_MAX; pin++) {
+ if (pin_cfg & BIT(pin))
+ break;
+ }
+
+ if (pin == PIN_ASSIGNMENT_MAX)
+ pin = PIN_ASSIGNMENT_C;
+
+ pr_debug("pin assignment: %s\n", mdss_dp_pin_name(pin));
+
+ config |= BIT(pin) << 8;
+
config |= (0x1 << 2); /* configure for DPv1.3 */
config |= 0x2; /* Configuring for UFP_D */