0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <drm/drm.h>
0012 #include <drm/drm_print.h>
0013 #include <drm/drm_probe_helper.h>
0014
0015 #include "udl_drv.h"
0016
0017
0018 #define BULK_SIZE 512
0019
0020 #define NR_USB_REQUEST_CHANNEL 0x12
0021
0022 #define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
0023 #define WRITES_IN_FLIGHT (4)
0024 #define MAX_VENDOR_DESCRIPTOR_SIZE 256
0025
0026 #define GET_URB_TIMEOUT HZ
0027 #define FREE_URB_TIMEOUT (HZ*2)
0028
0029 static int udl_parse_vendor_descriptor(struct udl_device *udl)
0030 {
0031 struct usb_device *udev = udl_to_usb_device(udl);
0032 char *desc;
0033 char *buf;
0034 char *desc_end;
0035
0036 u8 total_len = 0;
0037
0038 buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL);
0039 if (!buf)
0040 return false;
0041 desc = buf;
0042
0043 total_len = usb_get_descriptor(udev, 0x5f,
0044 0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
0045 if (total_len > 5) {
0046 DRM_INFO("vendor descriptor length:%x data:%11ph\n",
0047 total_len, desc);
0048
0049 if ((desc[0] != total_len) ||
0050 (desc[1] != 0x5f) ||
0051 (desc[2] != 0x01) ||
0052 (desc[3] != 0x00) ||
0053 (desc[4] != total_len - 2))
0054 goto unrecognized;
0055
0056 desc_end = desc + total_len;
0057 desc += 5;
0058
0059 while (desc < desc_end) {
0060 u8 length;
0061 u16 key;
0062
0063 key = le16_to_cpu(*((u16 *) desc));
0064 desc += sizeof(u16);
0065 length = *desc;
0066 desc++;
0067
0068 switch (key) {
0069 case 0x0200: {
0070 u32 max_area;
0071 max_area = le32_to_cpu(*((u32 *)desc));
0072 DRM_DEBUG("DL chip limited to %d pixel modes\n",
0073 max_area);
0074 udl->sku_pixel_limit = max_area;
0075 break;
0076 }
0077 default:
0078 break;
0079 }
0080 desc += length;
0081 }
0082 }
0083
0084 goto success;
0085
0086 unrecognized:
0087
0088 DRM_ERROR("Unrecognized vendor firmware descriptor\n");
0089
0090 success:
0091 kfree(buf);
0092 return true;
0093 }
0094
0095
0096
0097
0098 static int udl_select_std_channel(struct udl_device *udl)
0099 {
0100 static const u8 set_def_chn[] = {0x57, 0xCD, 0xDC, 0xA7,
0101 0x1C, 0x88, 0x5E, 0x15,
0102 0x60, 0xFE, 0xC6, 0x97,
0103 0x16, 0x3D, 0x47, 0xF2};
0104
0105 void *sendbuf;
0106 int ret;
0107 struct usb_device *udev = udl_to_usb_device(udl);
0108
0109 sendbuf = kmemdup(set_def_chn, sizeof(set_def_chn), GFP_KERNEL);
0110 if (!sendbuf)
0111 return -ENOMEM;
0112
0113 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
0114 NR_USB_REQUEST_CHANNEL,
0115 (USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
0116 sendbuf, sizeof(set_def_chn),
0117 USB_CTRL_SET_TIMEOUT);
0118 kfree(sendbuf);
0119 return ret < 0 ? ret : 0;
0120 }
0121
0122 static void udl_release_urb_work(struct work_struct *work)
0123 {
0124 struct urb_node *unode = container_of(work, struct urb_node,
0125 release_urb_work.work);
0126
0127 up(&unode->dev->urbs.limit_sem);
0128 }
0129
0130 void udl_urb_completion(struct urb *urb)
0131 {
0132 struct urb_node *unode = urb->context;
0133 struct udl_device *udl = unode->dev;
0134 unsigned long flags;
0135
0136
0137 if (urb->status) {
0138 if (!(urb->status == -ENOENT ||
0139 urb->status == -ECONNRESET ||
0140 urb->status == -ESHUTDOWN)) {
0141 DRM_ERROR("%s - nonzero write bulk status received: %d\n",
0142 __func__, urb->status);
0143 }
0144 }
0145
0146 urb->transfer_buffer_length = udl->urbs.size;
0147
0148 spin_lock_irqsave(&udl->urbs.lock, flags);
0149 list_add_tail(&unode->entry, &udl->urbs.list);
0150 udl->urbs.available++;
0151 spin_unlock_irqrestore(&udl->urbs.lock, flags);
0152
0153 #if 0
0154
0155
0156
0157
0158 if (fb_defio)
0159 schedule_delayed_work(&unode->release_urb_work, 0);
0160 else
0161 #endif
0162 up(&udl->urbs.limit_sem);
0163 }
0164
0165 static void udl_free_urb_list(struct drm_device *dev)
0166 {
0167 struct udl_device *udl = to_udl(dev);
0168 int count = udl->urbs.count;
0169 struct list_head *node;
0170 struct urb_node *unode;
0171 struct urb *urb;
0172
0173 DRM_DEBUG("Waiting for completes and freeing all render urbs\n");
0174
0175
0176 while (count--) {
0177 down(&udl->urbs.limit_sem);
0178
0179 spin_lock_irq(&udl->urbs.lock);
0180
0181 node = udl->urbs.list.next;
0182 list_del_init(node);
0183
0184 spin_unlock_irq(&udl->urbs.lock);
0185
0186 unode = list_entry(node, struct urb_node, entry);
0187 urb = unode->urb;
0188
0189
0190 usb_free_coherent(urb->dev, udl->urbs.size,
0191 urb->transfer_buffer, urb->transfer_dma);
0192 usb_free_urb(urb);
0193 kfree(node);
0194 }
0195 udl->urbs.count = 0;
0196 }
0197
0198 static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
0199 {
0200 struct udl_device *udl = to_udl(dev);
0201 struct urb *urb;
0202 struct urb_node *unode;
0203 char *buf;
0204 size_t wanted_size = count * size;
0205 struct usb_device *udev = udl_to_usb_device(udl);
0206
0207 spin_lock_init(&udl->urbs.lock);
0208
0209 retry:
0210 udl->urbs.size = size;
0211 INIT_LIST_HEAD(&udl->urbs.list);
0212
0213 sema_init(&udl->urbs.limit_sem, 0);
0214 udl->urbs.count = 0;
0215 udl->urbs.available = 0;
0216
0217 while (udl->urbs.count * size < wanted_size) {
0218 unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
0219 if (!unode)
0220 break;
0221 unode->dev = udl;
0222
0223 INIT_DELAYED_WORK(&unode->release_urb_work,
0224 udl_release_urb_work);
0225
0226 urb = usb_alloc_urb(0, GFP_KERNEL);
0227 if (!urb) {
0228 kfree(unode);
0229 break;
0230 }
0231 unode->urb = urb;
0232
0233 buf = usb_alloc_coherent(udev, size, GFP_KERNEL,
0234 &urb->transfer_dma);
0235 if (!buf) {
0236 kfree(unode);
0237 usb_free_urb(urb);
0238 if (size > PAGE_SIZE) {
0239 size /= 2;
0240 udl_free_urb_list(dev);
0241 goto retry;
0242 }
0243 break;
0244 }
0245
0246
0247 usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, 1),
0248 buf, size, udl_urb_completion, unode);
0249 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0250
0251 list_add_tail(&unode->entry, &udl->urbs.list);
0252
0253 up(&udl->urbs.limit_sem);
0254 udl->urbs.count++;
0255 udl->urbs.available++;
0256 }
0257
0258 DRM_DEBUG("allocated %d %d byte urbs\n", udl->urbs.count, (int) size);
0259
0260 return udl->urbs.count;
0261 }
0262
0263 struct urb *udl_get_urb(struct drm_device *dev)
0264 {
0265 struct udl_device *udl = to_udl(dev);
0266 int ret = 0;
0267 struct list_head *entry;
0268 struct urb_node *unode;
0269 struct urb *urb = NULL;
0270
0271
0272 ret = down_timeout(&udl->urbs.limit_sem, GET_URB_TIMEOUT);
0273 if (ret) {
0274 DRM_INFO("wait for urb interrupted: %x available: %d\n",
0275 ret, udl->urbs.available);
0276 goto error;
0277 }
0278
0279 spin_lock_irq(&udl->urbs.lock);
0280
0281 BUG_ON(list_empty(&udl->urbs.list));
0282 entry = udl->urbs.list.next;
0283 list_del_init(entry);
0284 udl->urbs.available--;
0285
0286 spin_unlock_irq(&udl->urbs.lock);
0287
0288 unode = list_entry(entry, struct urb_node, entry);
0289 urb = unode->urb;
0290
0291 error:
0292 return urb;
0293 }
0294
0295 int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len)
0296 {
0297 struct udl_device *udl = to_udl(dev);
0298 int ret;
0299
0300 BUG_ON(len > udl->urbs.size);
0301
0302 urb->transfer_buffer_length = len;
0303 ret = usb_submit_urb(urb, GFP_ATOMIC);
0304 if (ret) {
0305 udl_urb_completion(urb);
0306 DRM_ERROR("usb_submit_urb error %x\n", ret);
0307 }
0308 return ret;
0309 }
0310
0311 int udl_init(struct udl_device *udl)
0312 {
0313 struct drm_device *dev = &udl->drm;
0314 int ret = -ENOMEM;
0315
0316 DRM_DEBUG("\n");
0317
0318 udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev));
0319 if (!udl->dmadev)
0320 drm_warn(dev, "buffer sharing not supported");
0321
0322 mutex_init(&udl->gem_lock);
0323
0324 if (!udl_parse_vendor_descriptor(udl)) {
0325 ret = -ENODEV;
0326 DRM_ERROR("firmware not recognized. Assume incompatible device\n");
0327 goto err;
0328 }
0329
0330 if (udl_select_std_channel(udl))
0331 DRM_ERROR("Selecting channel failed\n");
0332
0333 if (!udl_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
0334 DRM_ERROR("udl_alloc_urb_list failed\n");
0335 goto err;
0336 }
0337
0338 DRM_DEBUG("\n");
0339 ret = udl_modeset_init(dev);
0340 if (ret)
0341 goto err;
0342
0343 drm_kms_helper_poll_init(dev);
0344
0345 return 0;
0346
0347 err:
0348 if (udl->urbs.count)
0349 udl_free_urb_list(dev);
0350 put_device(udl->dmadev);
0351 DRM_ERROR("%d\n", ret);
0352 return ret;
0353 }
0354
0355 int udl_drop_usb(struct drm_device *dev)
0356 {
0357 struct udl_device *udl = to_udl(dev);
0358
0359 udl_free_urb_list(dev);
0360 put_device(udl->dmadev);
0361 udl->dmadev = NULL;
0362
0363 return 0;
0364 }