Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2019 Hans de Goede <hdegoede@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/dma-buf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <drm/drm_atomic_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <drm/drm_atomic_state_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <drm/drm_connector.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <drm/drm_damage_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <drm/drm_drv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <drm/drm_fb_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <drm/drm_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <drm/drm_format_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <drm/drm_fourcc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <drm/drm_gem_shmem_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <drm/drm_gem_framebuffer_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <drm/drm_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <drm/drm_managed.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <drm/drm_modeset_helper_vtables.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <drm/drm_probe_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <drm/drm_simple_kms_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static bool eco_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) module_param(eco_mode, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define DRIVER_NAME		"gm12u320"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define DRIVER_DESC		"Grain Media GM12U320 USB projector display"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DRIVER_DATE		"2019"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define DRIVER_MAJOR		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define DRIVER_MINOR		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * The DLP has an actual width of 854 pixels, but that is not a multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * of 8, breaking things left and right, so we export a width of 848.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define GM12U320_USER_WIDTH		848
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define GM12U320_REAL_WIDTH		854
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define GM12U320_HEIGHT			480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define GM12U320_BLOCK_COUNT		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define GM12U320_ERR(fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	DRM_DEV_ERROR(&gm12u320->udev->dev, fmt, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define MISC_RCV_EPT			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define DATA_RCV_EPT			2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define DATA_SND_EPT			3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define MISC_SND_EPT			4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define DATA_BLOCK_HEADER_SIZE		84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define DATA_BLOCK_CONTENT_SIZE		64512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define DATA_BLOCK_FOOTER_SIZE		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define DATA_BLOCK_SIZE			(DATA_BLOCK_HEADER_SIZE + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 					 DATA_BLOCK_CONTENT_SIZE + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 					 DATA_BLOCK_FOOTER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define DATA_LAST_BLOCK_CONTENT_SIZE	4032
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define DATA_LAST_BLOCK_SIZE		(DATA_BLOCK_HEADER_SIZE + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 					 DATA_LAST_BLOCK_CONTENT_SIZE + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 					 DATA_BLOCK_FOOTER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define CMD_SIZE			31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define READ_STATUS_SIZE		13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define MISC_VALUE_SIZE			4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define CMD_TIMEOUT			msecs_to_jiffies(200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define DATA_TIMEOUT			msecs_to_jiffies(1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define IDLE_TIMEOUT			msecs_to_jiffies(2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define FIRST_FRAME_TIMEOUT		msecs_to_jiffies(2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define MISC_REQ_GET_SET_ECO_A		0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define MISC_REQ_GET_SET_ECO_B		0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) /* Windows driver does once every second, with arg d = 1, other args 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define MISC_REQ_UNKNOWN1_A		0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define MISC_REQ_UNKNOWN1_B		0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /* Windows driver does this on init, with arg a, b = 0, c = 0xa0, d = 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define MISC_REQ_UNKNOWN2_A		0xa5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define MISC_REQ_UNKNOWN2_B		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) struct gm12u320_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct drm_device	         dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct device                   *dmadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct drm_simple_display_pipe   pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct drm_connector	         conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct usb_device               *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	unsigned char                   *cmd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		struct delayed_work       work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		struct mutex             lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		struct drm_framebuffer  *fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		struct drm_rect          rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		int frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		int draw_status_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	} fb_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define to_gm12u320(__dev) container_of(__dev, struct gm12u320_device, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static const char cmd_data[CMD_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static const char cmd_draw[CMD_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	0x00, 0x00, 0x00, 0xc0, 0xd1, 0x05, 0x00, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const char cmd_misc[CMD_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	0x04, 0x00, 0x00, 0x00, 0x80, 0x01, 0x10, 0xfd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static const char data_block_header[DATA_BLOCK_HEADER_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	0x00, 0x04, 0x15, 0x00, 0x00, 0xfc, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	0x01, 0x00, 0x00, 0xdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static const char data_last_block_header[DATA_BLOCK_HEADER_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	0x2a, 0x00, 0x20, 0x00, 0xc0, 0x0f, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	0x01, 0x00, 0x00, 0xd7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static const char data_block_footer[DATA_BLOCK_FOOTER_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	0xfb, 0x14, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	0x80, 0x00, 0x00, 0x4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	int i, block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	const char *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	gm12u320->cmd_buf = drmm_kmalloc(&gm12u320->dev, CMD_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (!gm12u320->cmd_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	for (i = 0; i < GM12U320_BLOCK_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		if (i == GM12U320_BLOCK_COUNT - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			block_size = DATA_LAST_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			hdr = data_last_block_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			block_size = DATA_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			hdr = data_block_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		gm12u320->data_buf[i] = drmm_kzalloc(&gm12u320->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 						     block_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		if (!gm12u320->data_buf[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		memcpy(gm12u320->data_buf[i], hdr, DATA_BLOCK_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		memcpy(gm12u320->data_buf[i] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				(block_size - DATA_BLOCK_FOOTER_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		       data_block_footer, DATA_BLOCK_FOOTER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				 u8 req_a, u8 req_b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 				 u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	int ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	memcpy(gm12u320->cmd_buf, &cmd_misc, CMD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	gm12u320->cmd_buf[20] = req_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	gm12u320->cmd_buf[21] = req_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	gm12u320->cmd_buf[22] = arg_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	gm12u320->cmd_buf[23] = arg_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	gm12u320->cmd_buf[24] = arg_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	gm12u320->cmd_buf[25] = arg_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	/* Send request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			   usb_sndbulkpipe(gm12u320->udev, MISC_SND_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			   gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (ret || len != CMD_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		GM12U320_ERR("Misc. req. error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	/* Read value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			   usb_rcvbulkpipe(gm12u320->udev, MISC_RCV_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			   gm12u320->cmd_buf, MISC_VALUE_SIZE, &len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			   DATA_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (ret || len != MISC_VALUE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		GM12U320_ERR("Misc. value error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* cmd_buf[0] now contains the read value, which we don't use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/* Read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			   usb_rcvbulkpipe(gm12u320->udev, MISC_RCV_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			   gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			   CMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (ret || len != READ_STATUS_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		GM12U320_ERR("Misc. status error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void gm12u320_32bpp_to_24bpp_packed(u8 *dst, u8 *src, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	while (len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		*dst++ = *src++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		*dst++ = *src++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		*dst++ = *src++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		src++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	int block, dst_offset, len, remain, ret, x1, x2, y1, y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	struct drm_framebuffer *fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	void *vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	u8 *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	mutex_lock(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (!gm12u320->fb_update.fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	fb = gm12u320->fb_update.fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	x1 = gm12u320->fb_update.rect.x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	x2 = gm12u320->fb_update.rect.x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	y1 = gm12u320->fb_update.rect.y1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	y2 = gm12u320->fb_update.rect.y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	vaddr = drm_gem_shmem_vmap(fb->obj[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (IS_ERR(vaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		GM12U320_ERR("failed to vmap fb: %ld\n", PTR_ERR(vaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		goto put_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (fb->obj[0]->import_attach) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		ret = dma_buf_begin_cpu_access(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			fb->obj[0]->import_attach->dmabuf, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			GM12U320_ERR("dma_buf_begin_cpu_access err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			goto vunmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	src = vaddr + y1 * fb->pitches[0] + x1 * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	x1 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	x2 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	for (; y1 < y2; y1++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		remain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		len = (x2 - x1) * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		dst_offset = (y1 * GM12U320_REAL_WIDTH + x1) * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		block = dst_offset / DATA_BLOCK_CONTENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		dst_offset %= DATA_BLOCK_CONTENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		if ((dst_offset + len) > DATA_BLOCK_CONTENT_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			remain = dst_offset + len - DATA_BLOCK_CONTENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			len = DATA_BLOCK_CONTENT_SIZE - dst_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		dst_offset += DATA_BLOCK_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		len /= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		gm12u320_32bpp_to_24bpp_packed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			gm12u320->data_buf[block] + dst_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		if (remain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			block++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			dst_offset = DATA_BLOCK_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			gm12u320_32bpp_to_24bpp_packed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				gm12u320->data_buf[block] + dst_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 				src + len * 4, remain / 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		src += fb->pitches[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (fb->obj[0]->import_attach) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		ret = dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 					     DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			GM12U320_ERR("dma_buf_end_cpu_access err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) vunmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	drm_gem_shmem_vunmap(fb->obj[0], vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) put_fb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	drm_framebuffer_put(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	gm12u320->fb_update.fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	mutex_unlock(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static void gm12u320_fb_update_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	struct gm12u320_device *gm12u320 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		container_of(to_delayed_work(work), struct gm12u320_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			     fb_update.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	int block, block_size, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	gm12u320_copy_fb_to_blocks(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		if (block == GM12U320_BLOCK_COUNT - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			block_size = DATA_LAST_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			block_size = DATA_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		/* Send data command to device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		gm12u320->cmd_buf[8] = block_size & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		gm12u320->cmd_buf[9] = block_size >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		gm12u320->cmd_buf[20] = 0xfc - block * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		gm12u320->cmd_buf[21] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			block | (gm12u320->fb_update.frame << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			gm12u320->cmd_buf, CMD_SIZE, &len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			CMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		if (ret || len != CMD_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		/* Send data block to device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			gm12u320->data_buf[block], block_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			&len, DATA_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		if (ret || len != block_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		/* Read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			CMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		if (ret || len != READ_STATUS_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	/* Send draw command to device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (ret || len != CMD_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	/* Read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	ret = usb_bulk_msg(gm12u320->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		gm12u320->fb_update.draw_status_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	if (ret || len != READ_STATUS_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	gm12u320->fb_update.draw_status_timeout = CMD_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	gm12u320->fb_update.frame = !gm12u320->fb_update.frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	 * We must draw a frame every 2s otherwise the projector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	 * switches back to showing its logo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			   IDLE_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	/* Do not log errors caused by module unload or device unplug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (ret != -ENODEV && ret != -ECONNRESET && ret != -ESHUTDOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		GM12U320_ERR("Frame update error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 				   struct drm_rect *dirty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	struct drm_framebuffer *old_fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	bool wakeup = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	mutex_lock(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	if (gm12u320->fb_update.fb != fb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		old_fb = gm12u320->fb_update.fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		drm_framebuffer_get(fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		gm12u320->fb_update.fb = fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		gm12u320->fb_update.rect = *dirty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		wakeup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		struct drm_rect *rect = &gm12u320->fb_update.rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		rect->x1 = min(rect->x1, dirty->x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		rect->y1 = min(rect->y1, dirty->y1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		rect->x2 = max(rect->x2, dirty->x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		rect->y2 = max(rect->y2, dirty->y2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	mutex_unlock(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		mod_delayed_work(system_long_wq, &gm12u320->fb_update.work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	if (old_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		drm_framebuffer_put(old_fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	struct drm_framebuffer *old_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	cancel_delayed_work_sync(&gm12u320->fb_update.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	mutex_lock(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	old_fb = gm12u320->fb_update.fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	gm12u320->fb_update.fb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	mutex_unlock(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	drm_framebuffer_put(old_fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	return gm12u320_misc_request(gm12u320, MISC_REQ_GET_SET_ECO_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				     MISC_REQ_GET_SET_ECO_B, 0x01 /* set */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				     eco_mode ? 0x01 : 0x00, 0x00, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* gm12u320 connector						      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)  * We use fake EDID info so that userspace know that it is dealing with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)  * an Acer projector, rather then listing this as an "unknown" monitor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)  * Note this assumes this driver is only ever used with the Acer C120, if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  * add support for other devices the vendor and model should be parameterized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static struct edid gm12u320_edid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	.header		= { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	.mfg_id		= { 0x04, 0x72 },	/* "ACR" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	.prod_code	= { 0x20, 0xc1 },	/* C120h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	.serial		= 0xaa55aa55,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	.mfg_week	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	.mfg_year	= 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	.version	= 1,			/* EDID 1.3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	.revision	= 3,			/* EDID 1.3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	.input		= 0x08,			/* Analog input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	.features	= 0x0a,			/* Pref timing in DTD 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	.standard_timings = { { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			      { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	.detailed_timings = { {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		.pixel_clock = 3383,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		/* hactive = 848, hblank = 256 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		.data.pixel_data.hactive_lo = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		.data.pixel_data.hblank_lo = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		.data.pixel_data.hactive_hblank_hi = 0x31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		/* vactive = 480, vblank = 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		.data.pixel_data.vactive_lo = 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		.data.pixel_data.vblank_lo = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		.data.pixel_data.vactive_vblank_hi = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		/* hsync offset 40 pw 128, vsync offset 1 pw 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		.data.pixel_data.hsync_offset_lo = 0x28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		.data.pixel_data.hsync_pulse_width_lo = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		.data.pixel_data.vsync_offset_pulse_width_lo = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		.data.pixel_data.hsync_vsync_offset_pulse_width_hi = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		/* Digital separate syncs, hsync+, vsync+ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		.data.pixel_data.misc = 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		.pixel_clock = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		.data.other_data.type = 0xfd, /* Monitor ranges */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		.data.other_data.data.range.min_vfreq = 59,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		.data.other_data.data.range.max_vfreq = 61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		.data.other_data.data.range.min_hfreq_khz = 29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		.data.other_data.data.range.max_hfreq_khz = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		.data.other_data.data.range.pixel_clock_mhz = 4, /* 40 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		.data.other_data.data.range.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		.data.other_data.data.range.formula.cvt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 			0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		.pixel_clock = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		.data.other_data.type = 0xfc, /* Model string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		.data.other_data.data.str.str = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 			'P', 'r', 'o', 'j', 'e', 'c', 't', 'o', 'r', '\n',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			' ', ' ',  ' ' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		.pixel_clock = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		.data.other_data.type = 0xfe, /* Unspecified text / padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		.data.other_data.data.str.str = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			'\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			' ', ' ',  ' ' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	.checksum = 0x13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int gm12u320_conn_get_modes(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	drm_connector_update_edid_property(connector, &gm12u320_edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	return drm_add_edid_modes(connector, &gm12u320_edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	.get_modes = gm12u320_conn_get_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static const struct drm_connector_funcs gm12u320_conn_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	.fill_modes = drm_helper_probe_single_connector_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	.destroy = drm_connector_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	.reset = drm_atomic_helper_connector_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int gm12u320_conn_init(struct gm12u320_device *gm12u320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	return drm_connector_init(&gm12u320->dev, &gm12u320->conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				  &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* gm12u320 (simple) display pipe				      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 				 struct drm_crtc_state *crtc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 				 struct drm_plane_state *plane_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	gm12u320_fb_mark_dirty(plane_state->fb, &rect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	gm12u320_stop_fb_update(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 				 struct drm_plane_state *old_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	struct drm_plane_state *state = pipe->plane.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	struct drm_rect rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (drm_atomic_helper_damage_merged(old_state, state, &rect))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		gm12u320_fb_mark_dirty(pipe->plane.state->fb, &rect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	.enable	    = gm12u320_pipe_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	.disable    = gm12u320_pipe_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	.update	    = gm12u320_pipe_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static const uint32_t gm12u320_pipe_formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	DRM_FORMAT_XRGB8888,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static const uint64_t gm12u320_pipe_modifiers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	DRM_FORMAT_MOD_LINEAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	DRM_FORMAT_MOD_INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)  * FIXME: Dma-buf sharing requires DMA support by the importing device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)  *        This function is a workaround to make USB devices work as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)  *        See todo.rst for how to fix the issue in the dma-buf framework.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 							struct dma_buf *dma_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	struct gm12u320_device *gm12u320 = to_gm12u320(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	if (!gm12u320->dmadev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) DEFINE_DRM_GEM_FOPS(gm12u320_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static struct drm_driver gm12u320_drm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	.name		 = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	.desc		 = DRIVER_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	.date		 = DRIVER_DATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	.major		 = DRIVER_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	.minor		 = DRIVER_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	.fops		 = &gm12u320_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	DRM_GEM_SHMEM_DRIVER_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	.gem_prime_import = gm12u320_gem_prime_import,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	.fb_create = drm_gem_fb_create_with_dirty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	.atomic_check = drm_atomic_helper_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	.atomic_commit = drm_atomic_helper_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int gm12u320_usb_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			      const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	struct gm12u320_device *gm12u320;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	struct drm_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	 * The gm12u320 presents itself to the system as 2 usb mass-storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	 * interfaces, we only care about / need the first one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	if (interface->cur_altsetting->desc.bInterfaceNumber != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	gm12u320 = devm_drm_dev_alloc(&interface->dev, &gm12u320_drm_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 				      struct gm12u320_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	if (IS_ERR(gm12u320))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		return PTR_ERR(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	dev = &gm12u320->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	if (!gm12u320->dmadev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		drm_warn(dev, "buffer sharing not supported"); /* not an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	gm12u320->udev = interface_to_usbdev(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	mutex_init(&gm12u320->fb_update.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	ret = drmm_mode_config_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		goto err_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	dev->mode_config.min_width = GM12U320_USER_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	dev->mode_config.max_width = GM12U320_USER_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	dev->mode_config.min_height = GM12U320_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	dev->mode_config.max_height = GM12U320_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	dev->mode_config.funcs = &gm12u320_mode_config_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	ret = gm12u320_usb_alloc(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		goto err_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	ret = gm12u320_set_ecomode(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		goto err_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	ret = gm12u320_conn_init(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		goto err_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	ret = drm_simple_display_pipe_init(&gm12u320->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 					   &gm12u320->pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 					   &gm12u320_pipe_funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 					   gm12u320_pipe_formats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 					   ARRAY_SIZE(gm12u320_pipe_formats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 					   gm12u320_pipe_modifiers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 					   &gm12u320->conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		goto err_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	drm_mode_config_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	usb_set_intfdata(interface, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	ret = drm_dev_register(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		goto err_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	drm_fbdev_generic_setup(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) err_put_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	put_device(gm12u320->dmadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static void gm12u320_usb_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	struct drm_device *dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	struct gm12u320_device *gm12u320 = to_gm12u320(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	put_device(gm12u320->dmadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	gm12u320->dmadev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	drm_dev_unplug(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	drm_atomic_helper_shutdown(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 					   pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	struct drm_device *dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	return drm_mode_config_helper_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	struct drm_device *dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	struct gm12u320_device *gm12u320 = to_gm12u320(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	gm12u320_set_ecomode(gm12u320);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	return drm_mode_config_helper_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	{ USB_DEVICE(0x1de1, 0xc102) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static struct usb_driver gm12u320_usb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	.name = "gm12u320",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	.probe = gm12u320_usb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	.disconnect = gm12u320_usb_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	.id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	.suspend = gm12u320_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	.resume = gm12u320_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	.reset_resume = gm12u320_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) module_usb_driver(gm12u320_usb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) MODULE_LICENSE("GPL");