• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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