1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "mipi_dsi_test.h"
10 #include "hdf_log.h"
11
12 #define HDF_LOG_TAG mipi_dsi_test
13
MipiDsiTestMallocBuf(struct MipiDsiTest * test)14 static int32_t MipiDsiTestMallocBuf(struct MipiDsiTest *test)
15 {
16 static uint8_t buf = 0x29;
17
18 test->msgs.dataType = 0x05; /* 0x05: data type */
19 test->msgs.dataLen = 1; /* 1: data len */
20 test->msgs.delay = 0;
21 test->msgs.payload = &buf;
22
23 return HDF_SUCCESS;
24 }
25
MipiDsiTestSetUp(struct MipiDsiTest * test)26 static int32_t MipiDsiTestSetUp(struct MipiDsiTest *test)
27 {
28 if (test == NULL) {
29 return HDF_ERR_INVALID_OBJECT;
30 }
31
32 if (test->handle == NULL) {
33 test->handle = MipiDsiOpen(test->devNo);
34 }
35 if (test->handle == NULL) {
36 HDF_LOGE("%s: fail!", __func__);
37 return HDF_FAILURE;
38 }
39
40 test->fails = 0;
41 HDF_LOGD("%s: devNo:0x%x", __func__, test->devNo);
42 return MipiDsiTestMallocBuf(test);
43 }
44
MipiDsiTestTearDown(struct MipiDsiTest * test)45 static void MipiDsiTestTearDown(struct MipiDsiTest *test)
46 {
47 if (test == NULL) {
48 return;
49 }
50 if (test->handle != NULL) {
51 MipiDsiClose(test->handle);
52 test->handle = NULL;
53 }
54 }
55
CmpStVal(struct MipiCfg * a,struct MipiCfg * b)56 static int32_t CmpStVal(struct MipiCfg *a, struct MipiCfg *b)
57 {
58 if (a->lane == b->lane &&
59 a->mode == b->mode &&
60 a->format == b->format &&
61 a->burstMode == b->burstMode &&
62 a->pixelClk == b->pixelClk &&
63 a->phyDataRate == b->phyDataRate &&
64 a->timing.xPixels == b->timing.xPixels &&
65 a->timing.hsaPixels == b->timing.hsaPixels &&
66 a->timing.hbpPixels == b->timing.hbpPixels &&
67 a->timing.hlinePixels == b->timing.hlinePixels &&
68 a->timing.vsaLines == b->timing.vsaLines &&
69 a->timing.vbpLines == b->timing.vbpLines &&
70 a->timing.vfpLines == b->timing.vfpLines &&
71 a->timing.ylines == b->timing.ylines &&
72 a->timing.edpiCmdSize == b->timing.edpiCmdSize) {
73 return true;
74 }
75 return false;
76 }
77
MipiDsiGetCfgTest(struct MipiDsiTest * test)78 static int32_t MipiDsiGetCfgTest(struct MipiDsiTest *test)
79 {
80 int32_t ret;
81 struct MipiCfg cfg;
82
83 ret = MipiDsiGetCfg(test->handle, &cfg);
84 if (ret == HDF_SUCCESS) {
85 if (CmpStVal(&cfg, &test->cfg)) {
86 return HDF_SUCCESS;
87 }
88 }
89 return HDF_FAILURE;
90 }
91
MipiDsiTxRxTest(struct MipiDsiTest * test)92 static int32_t MipiDsiTxRxTest(struct MipiDsiTest *test)
93 {
94 int32_t ret;
95 uint8_t data = 0x0A; /* 0x0A: lcd status reg */
96 struct DsiCmdDesc cmd = {
97 .dataType = 0x06, /* 0x06: read data type */
98 .dataLen = 1, /* 1: data len */
99 .delay = 0,
100 .payload = &data,
101 };
102 uint8_t buf = 0;
103
104 ret = MipiDsiTx(test->handle, &test->msgs);
105 if (ret == HDF_SUCCESS) {
106 ret = MipiDsiRx(test->handle, &cmd, 1, &buf); /* 1: read len */
107 if (ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT) {
108 return HDF_SUCCESS;
109 }
110 } else if (ret == HDF_ERR_NOT_SUPPORT) {
111 return HDF_SUCCESS;
112 }
113 HDF_LOGE("%s: fail", __func__);
114 return HDF_FAILURE;
115 }
116
MipiDsiToLpToHsTest(struct MipiDsiTest * test)117 static int32_t MipiDsiToLpToHsTest(struct MipiDsiTest *test)
118 {
119 MipiDsiSetHsMode(test->handle);
120 MipiDsiSetLpMode(test->handle);
121 return HDF_SUCCESS;
122 }
123
MipiDsiTestByCmd(struct MipiDsiTest * test,int32_t cmd)124 static int32_t MipiDsiTestByCmd(struct MipiDsiTest *test, int32_t cmd)
125 {
126 int32_t ret = HDF_FAILURE;
127
128 switch (cmd) {
129 case MIPI_DSI_TEST_SET_CFG:
130 ret = MipiDsiSetCfg(test->handle, &test->cfg);
131 break;
132 case MIPI_DSI_TEST_GET_CFG:
133 ret = MipiDsiGetCfgTest(test);
134 break;
135 case MIPI_DSI_TEST_TX_RX:
136 ret = MipiDsiTxRxTest(test);
137 break;
138 case MIPI_DSI_TEST_TO_LP_TO_HS:
139 ret = MipiDsiToLpToHsTest(test);
140 break;
141 default:
142 HDF_LOGE("%s: not support", __func__);
143 break;
144 }
145 HDF_LOGI("test cmd %u, ret %d", cmd, ret);
146 return ret;
147 }
148
MipiDsiTestDoTest(struct MipiDsiTest * test,int32_t cmd)149 static int32_t MipiDsiTestDoTest(struct MipiDsiTest *test, int32_t cmd)
150 {
151 int32_t ret;
152
153 if (test == NULL) {
154 return HDF_ERR_INVALID_OBJECT;
155 }
156 ret = MipiDsiTestSetUp(test);
157 if (ret != HDF_SUCCESS) {
158 HDF_LOGE("%s: setup fail!", __func__);
159 return ret;
160 }
161 #ifdef MIPI_DSI_TEST_ON_INIT
162 int32_t i;
163 for (i = 0; i < test->total; i++) {
164 if (MipiDsiTestByCmd(test, i) != HDF_SUCCESS) {
165 test->fails++;
166 }
167 }
168 HDF_LOGI("\n\n%s: **********PASS:%u FAIL:%u**************\n\n",
169 __func__, test->total - test->fails, test->fails);
170 ret = (test->fails > 0) ? HDF_FAILURE : HDF_SUCCESS;
171 #else
172 ret = MipiDsiTestByCmd(test, cmd);
173 #endif
174 MipiDsiTestTearDown(test);
175 return ret;
176 }
177
MipiDsiTestBind(struct HdfDeviceObject * device)178 static int32_t MipiDsiTestBind(struct HdfDeviceObject *device)
179 {
180 static struct MipiDsiTest test;
181
182 test.cfg.lane = DSI_2_LANES;
183 test.cfg.mode = DSI_VIDEO_MODE;
184 test.cfg.format = FORMAT_RGB_24_BIT;
185 test.cfg.burstMode = VIDEO_BURST_MODE;
186 test.cfg.timing.xPixels = 480; /* 480: width */
187 test.cfg.timing.hsaPixels = 10; /* 10: horizontal sync porch */
188 test.cfg.timing.hbpPixels = 20; /* 20: horizontal back porch */
189 test.cfg.timing.hlinePixels = 530; /* 530: horizontal total width */
190 test.cfg.timing.vsaLines = 2; /* 2: vertiacl sync width */
191 test.cfg.timing.vbpLines = 14; /* 14: vertiacl back porch */
192 test.cfg.timing.vfpLines = 16; /* 16: vertiacl front porch */
193 test.cfg.timing.ylines = 960; /* 960: height */
194 /* 0 : no care */
195 test.cfg.timing.edpiCmdSize = 0;
196 /*
197 * pixel clk(kHZ):
198 * calculate: (width + hbp + hfp + hsw) * (height + vbp + vfp + vsw) * frameRate / 1000
199 */
200 test.cfg.pixelClk = 31546; /* 31546: pixel clk */
201 /*
202 * phy data rate(Mbps):
203 * calculate: (pixelClk / 1000) * 24 / laneNum
204 */
205 test.cfg.phyDataRate = 379; /* 379: mipi clk */
206 test.devNo = 0;
207 test.total = MIPI_DSI_TEST_MAX;
208 test.doTest = MipiDsiTestDoTest;
209 device->service = &test.service;
210 #ifdef MIPI_DSI_TEST_ON_INIT
211 HDF_LOGI("%s: test on init!", __func__);
212 test.doTest(&test, -1);
213 #endif
214 return HDF_SUCCESS;
215 }
216
MipiDsiTestInit(struct HdfDeviceObject * device)217 static int32_t MipiDsiTestInit(struct HdfDeviceObject *device)
218 {
219 (void)device;
220 return HDF_SUCCESS;
221 }
222
223 struct HdfDriverEntry g_mipiDsiTestEntry = {
224 .moduleVersion = 1,
225 .Bind = MipiDsiTestBind,
226 .Init = MipiDsiTestInit,
227 .moduleName = "PLATFORM_MIPI_DSI_TEST",
228 };
229 HDF_INIT(g_mipiDsiTestEntry);
230