hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/drm_mipi_dsi.c
....@@ -33,6 +33,8 @@
3333 #include <linux/pm_runtime.h>
3434 #include <linux/slab.h>
3535
36
+#include <drm/drm_dsc.h>
37
+#include <drm/drm_print.h>
3638 #include <video/mipi_display.h>
3739
3840 /**
....@@ -93,11 +95,6 @@
9395 .pm = &mipi_dsi_device_pm_ops,
9496 };
9597
96
-static int of_device_match(struct device *dev, void *data)
97
-{
98
- return dev->of_node == data;
99
-}
100
-
10198 /**
10299 * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
103100 * device tree node
....@@ -110,7 +107,7 @@
110107 {
111108 struct device *dev;
112109
113
- dev = bus_find_device(&mipi_dsi_bus_type, NULL, np, of_device_match);
110
+ dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np);
114111
115112 return dev ? to_mipi_dsi_device(dev) : NULL;
116113 }
....@@ -159,19 +156,18 @@
159156 static struct mipi_dsi_device *
160157 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
161158 {
162
- struct device *dev = host->dev;
163159 struct mipi_dsi_device_info info = { };
164160 int ret;
165161 u32 reg;
166162
167163 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
168
- dev_err(dev, "modalias failure on %pOF\n", node);
164
+ drm_err(host, "modalias failure on %pOF\n", node);
169165 return ERR_PTR(-EINVAL);
170166 }
171167
172168 ret = of_property_read_u32(node, "reg", &reg);
173169 if (ret) {
174
- dev_err(dev, "device node %pOF has no valid reg property: %d\n",
170
+ drm_err(host, "device node %pOF has no valid reg property: %d\n",
175171 node, ret);
176172 return ERR_PTR(-EINVAL);
177173 }
....@@ -206,33 +202,32 @@
206202 const struct mipi_dsi_device_info *info)
207203 {
208204 struct mipi_dsi_device *dsi;
209
- struct device *dev = host->dev;
210205 int ret;
211206
212207 if (!info) {
213
- dev_err(dev, "invalid mipi_dsi_device_info pointer\n");
208
+ drm_err(host, "invalid mipi_dsi_device_info pointer\n");
214209 return ERR_PTR(-EINVAL);
215210 }
216211
217212 if (info->channel > 3) {
218
- dev_err(dev, "invalid virtual channel: %u\n", info->channel);
213
+ drm_err(host, "invalid virtual channel: %u\n", info->channel);
219214 return ERR_PTR(-EINVAL);
220215 }
221216
222217 dsi = mipi_dsi_device_alloc(host);
223218 if (IS_ERR(dsi)) {
224
- dev_err(dev, "failed to allocate DSI device %ld\n",
219
+ drm_err(host, "failed to allocate DSI device %ld\n",
225220 PTR_ERR(dsi));
226221 return dsi;
227222 }
228223
229
- dsi->dev.of_node = info->node;
224
+ device_set_node(&dsi->dev, of_fwnode_handle(info->node));
230225 dsi->channel = info->channel;
231226 strlcpy(dsi->name, info->type, sizeof(dsi->name));
232227
233228 ret = mipi_dsi_device_add(dsi);
234229 if (ret) {
235
- dev_err(dev, "failed to add DSI device %d\n", ret);
230
+ drm_err(host, "failed to add DSI device %d\n", ret);
236231 kfree(dsi);
237232 return ERR_PTR(ret);
238233 }
....@@ -305,6 +300,7 @@
305300 {
306301 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
307302
303
+ mipi_dsi_detach(dsi);
308304 mipi_dsi_device_unregister(dsi);
309305
310306 return 0;
....@@ -379,6 +375,7 @@
379375 case MIPI_DSI_V_SYNC_END:
380376 case MIPI_DSI_H_SYNC_START:
381377 case MIPI_DSI_H_SYNC_END:
378
+ case MIPI_DSI_COMPRESSION_MODE:
382379 case MIPI_DSI_END_OF_TRANSMISSION:
383380 case MIPI_DSI_COLOR_MODE_OFF:
384381 case MIPI_DSI_COLOR_MODE_ON:
....@@ -393,7 +390,7 @@
393390 case MIPI_DSI_DCS_SHORT_WRITE:
394391 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
395392 case MIPI_DSI_DCS_READ:
396
- case MIPI_DSI_DCS_COMPRESSION_MODE:
393
+ case MIPI_DSI_EXECUTE_QUEUE:
397394 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
398395 return true;
399396 }
....@@ -412,11 +409,12 @@
412409 bool mipi_dsi_packet_format_is_long(u8 type)
413410 {
414411 switch (type) {
415
- case MIPI_DSI_PPS_LONG_WRITE:
416412 case MIPI_DSI_NULL_PACKET:
417413 case MIPI_DSI_BLANKING_PACKET:
418414 case MIPI_DSI_GENERIC_LONG_WRITE:
419415 case MIPI_DSI_DCS_LONG_WRITE:
416
+ case MIPI_DSI_PICTURE_PARAMETER_SET:
417
+ case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
420418 case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
421419 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
422420 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
....@@ -551,6 +549,56 @@
551549 return (ret < 0) ? ret : 0;
552550 }
553551 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
552
+
553
+/**
554
+ * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
555
+ * @dsi: DSI peripheral device
556
+ * @enable: Whether to enable or disable the DSC
557
+ *
558
+ * Enable or disable Display Stream Compression on the peripheral using the
559
+ * default Picture Parameter Set and VESA DSC 1.1 algorithm.
560
+ *
561
+ * Return: 0 on success or a negative error code on failure.
562
+ */
563
+ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
564
+{
565
+ /* Note: Needs updating for non-default PPS or algorithm */
566
+ u8 tx[2] = { enable << 0, 0 };
567
+ struct mipi_dsi_msg msg = {
568
+ .channel = dsi->channel,
569
+ .type = MIPI_DSI_COMPRESSION_MODE,
570
+ .tx_len = sizeof(tx),
571
+ .tx_buf = tx,
572
+ };
573
+ int ret = mipi_dsi_device_transfer(dsi, &msg);
574
+
575
+ return (ret < 0) ? ret : 0;
576
+}
577
+EXPORT_SYMBOL(mipi_dsi_compression_mode);
578
+
579
+/**
580
+ * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
581
+ * @dsi: DSI peripheral device
582
+ * @pps: VESA DSC 1.1 Picture Parameter Set
583
+ *
584
+ * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
585
+ *
586
+ * Return: 0 on success or a negative error code on failure.
587
+ */
588
+ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
589
+ const struct drm_dsc_picture_parameter_set *pps)
590
+{
591
+ struct mipi_dsi_msg msg = {
592
+ .channel = dsi->channel,
593
+ .type = MIPI_DSI_PICTURE_PARAMETER_SET,
594
+ .tx_len = sizeof(*pps),
595
+ .tx_buf = pps,
596
+ };
597
+ int ret = mipi_dsi_device_transfer(dsi, &msg);
598
+
599
+ return (ret < 0) ? ret : 0;
600
+}
601
+EXPORT_SYMBOL(mipi_dsi_picture_parameter_set);
554602
555603 /**
556604 * mipi_dsi_generic_write() - transmit data using a generic write packet
....@@ -701,26 +749,26 @@
701749 {
702750 ssize_t err;
703751 size_t size;
752
+ u8 stack_tx[8];
704753 u8 *tx;
705754
706
- if (len > 0) {
707
- size = 1 + len;
708
-
755
+ size = 1 + len;
756
+ if (len > ARRAY_SIZE(stack_tx) - 1) {
709757 tx = kmalloc(size, GFP_KERNEL);
710758 if (!tx)
711759 return -ENOMEM;
712
-
713
- /* concatenate the DCS command byte and the payload */
714
- tx[0] = cmd;
715
- memcpy(&tx[1], data, len);
716760 } else {
717
- tx = &cmd;
718
- size = 1;
761
+ tx = stack_tx;
719762 }
763
+
764
+ /* concatenate the DCS command byte and the payload */
765
+ tx[0] = cmd;
766
+ if (data)
767
+ memcpy(&tx[1], data, len);
720768
721769 err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
722770
723
- if (len > 0)
771
+ if (tx != stack_tx)
724772 kfree(tx);
725773
726774 return err;
....@@ -1096,6 +1144,58 @@
10961144 }
10971145 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
10981146
1147
+/**
1148
+ * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
1149
+ * of the display
1150
+ * @dsi: DSI peripheral device
1151
+ * @brightness: brightness value
1152
+ *
1153
+ * Return: 0 on success or a negative error code on failure.
1154
+ */
1155
+int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
1156
+ u16 brightness)
1157
+{
1158
+ u8 payload[2] = { brightness >> 8, brightness & 0xff };
1159
+ ssize_t err;
1160
+
1161
+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1162
+ payload, sizeof(payload));
1163
+ if (err < 0)
1164
+ return err;
1165
+
1166
+ return 0;
1167
+}
1168
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
1169
+
1170
+/**
1171
+ * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
1172
+ * brightness value of the display
1173
+ * @dsi: DSI peripheral device
1174
+ * @brightness: brightness value
1175
+ *
1176
+ * Return: 0 on success or a negative error code on failure.
1177
+ */
1178
+int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
1179
+ u16 *brightness)
1180
+{
1181
+ u8 brightness_be[2];
1182
+ ssize_t err;
1183
+
1184
+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1185
+ brightness_be, sizeof(brightness_be));
1186
+ if (err <= 0) {
1187
+ if (err == 0)
1188
+ err = -ENODATA;
1189
+
1190
+ return err;
1191
+ }
1192
+
1193
+ *brightness = (brightness_be[0] << 8) | brightness_be[1];
1194
+
1195
+ return 0;
1196
+}
1197
+EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
1198
+
10991199 static int mipi_dsi_drv_probe(struct device *dev)
11001200 {
11011201 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);