Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OMAPDSS: Merge omapdss topic branches

+1606 -1247
+25 -2
drivers/gpu/drm/omapdrm/omap_connector.c
··· 110 110 ret = connector_status_connected; 111 111 else 112 112 ret = connector_status_disconnected; 113 + } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI || 114 + dssdev->type == OMAP_DISPLAY_TYPE_DBI || 115 + dssdev->type == OMAP_DISPLAY_TYPE_SDI || 116 + dssdev->type == OMAP_DISPLAY_TYPE_DSI) { 117 + ret = connector_status_connected; 113 118 } else { 114 119 ret = connector_status_unknown; 115 120 } ··· 194 189 struct omap_video_timings timings = {0}; 195 190 struct drm_device *dev = connector->dev; 196 191 struct drm_display_mode *new_mode; 197 - int ret = MODE_BAD; 192 + int r, ret = MODE_BAD; 198 193 199 194 copy_timings_drm_to_omap(&timings, mode); 200 195 mode->vrefresh = drm_mode_vrefresh(mode); 201 196 202 - if (!dssdrv->check_timings(dssdev, &timings)) { 197 + /* 198 + * if the panel driver doesn't have a check_timings, it's most likely 199 + * a fixed resolution panel, check if the timings match with the 200 + * panel's timings 201 + */ 202 + if (dssdrv->check_timings) { 203 + r = dssdrv->check_timings(dssdev, &timings); 204 + } else { 205 + struct omap_video_timings t = {0}; 206 + 207 + dssdrv->get_timings(dssdev, &t); 208 + 209 + if (memcmp(&timings, &t, sizeof(struct omap_video_timings))) 210 + r = -EINVAL; 211 + else 212 + r = 0; 213 + } 214 + 215 + if (!r) { 203 216 /* check if vrefresh is still valid */ 204 217 new_mode = drm_mode_duplicate(dev, mode); 205 218 new_mode->clock = timings.pixel_clock;
+14 -7
drivers/gpu/drm/omapdrm/omap_crtc.c
··· 74 74 struct work_struct page_flip_work; 75 75 }; 76 76 77 + uint32_t pipe2vbl(struct drm_crtc *crtc) 78 + { 79 + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 80 + 81 + return dispc_mgr_get_vsync_irq(omap_crtc->channel); 82 + } 83 + 77 84 /* 78 85 * Manager-ops, callbacks from output when they need to configure 79 86 * the upstream part of the video pipe. ··· 620 613 omap_crtc->apply.pre_apply = omap_crtc_pre_apply; 621 614 omap_crtc->apply.post_apply = omap_crtc_post_apply; 622 615 623 - omap_crtc->apply_irq.irqmask = pipe2vbl(id); 616 + omap_crtc->channel = channel; 617 + omap_crtc->plane = plane; 618 + omap_crtc->plane->crtc = crtc; 619 + omap_crtc->name = channel_names[channel]; 620 + omap_crtc->pipe = id; 621 + 622 + omap_crtc->apply_irq.irqmask = pipe2vbl(crtc); 624 623 omap_crtc->apply_irq.irq = omap_crtc_apply_irq; 625 624 626 625 omap_crtc->error_irq.irqmask = 627 626 dispc_mgr_get_sync_lost_irq(channel); 628 627 omap_crtc->error_irq.irq = omap_crtc_error_irq; 629 628 omap_irq_register(dev, &omap_crtc->error_irq); 630 - 631 - omap_crtc->channel = channel; 632 - omap_crtc->plane = plane; 633 - omap_crtc->plane->crtc = crtc; 634 - omap_crtc->name = channel_names[channel]; 635 - omap_crtc->pipe = id; 636 629 637 630 /* temporary: */ 638 631 omap_crtc->mgr.id = channel;
+133 -32
drivers/gpu/drm/omapdrm/omap_drv.c
··· 74 74 } 75 75 } 76 76 77 + static bool channel_used(struct drm_device *dev, enum omap_channel channel) 78 + { 79 + struct omap_drm_private *priv = dev->dev_private; 80 + int i; 81 + 82 + for (i = 0; i < priv->num_crtcs; i++) { 83 + struct drm_crtc *crtc = priv->crtcs[i]; 84 + 85 + if (omap_crtc_channel(crtc) == channel) 86 + return true; 87 + } 88 + 89 + return false; 90 + } 91 + 77 92 static int omap_modeset_init(struct drm_device *dev) 78 93 { 79 94 struct omap_drm_private *priv = dev->dev_private; 80 95 struct omap_dss_device *dssdev = NULL; 81 96 int num_ovls = dss_feat_get_num_ovls(); 82 - int id; 97 + int num_mgrs = dss_feat_get_num_mgrs(); 98 + int num_crtcs; 99 + int i, id = 0; 83 100 84 101 drm_mode_config_init(dev); 85 102 86 103 omap_drm_irq_install(dev); 87 104 88 105 /* 89 - * Create private planes and CRTCs for the last NUM_CRTCs overlay 90 - * plus manager: 106 + * We usually don't want to create a CRTC for each manager, at least 107 + * not until we have a way to expose private planes to userspace. 108 + * Otherwise there would not be enough video pipes left for drm planes. 109 + * We use the num_crtc argument to limit the number of crtcs we create. 91 110 */ 92 - for (id = 0; id < min(num_crtc, num_ovls); id++) { 93 - struct drm_plane *plane; 94 - struct drm_crtc *crtc; 111 + num_crtcs = min3(num_crtc, num_mgrs, num_ovls); 95 112 96 - plane = omap_plane_init(dev, id, true); 97 - crtc = omap_crtc_init(dev, plane, pipe2chan(id), id); 98 - 99 - BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); 100 - priv->crtcs[id] = crtc; 101 - priv->num_crtcs++; 102 - 103 - priv->planes[id] = plane; 104 - priv->num_planes++; 105 - } 106 - 107 - /* 108 - * Create normal planes for the remaining overlays: 109 - */ 110 - for (; id < num_ovls; id++) { 111 - struct drm_plane *plane = omap_plane_init(dev, id, false); 112 - 113 - BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); 114 - priv->planes[priv->num_planes++] = plane; 115 - } 113 + dssdev = NULL; 116 114 117 115 for_each_dss_dev(dssdev) { 118 116 struct drm_connector *connector; 119 117 struct drm_encoder *encoder; 118 + enum omap_channel channel; 120 119 121 120 if (!dssdev->driver) { 122 121 dev_warn(dev->dev, "%s has no driver.. skipping it\n", 123 122 dssdev->name); 124 - return 0; 123 + continue; 125 124 } 126 125 127 126 if (!(dssdev->driver->get_timings || ··· 128 129 dev_warn(dev->dev, "%s driver does not support " 129 130 "get_timings or read_edid.. skipping it!\n", 130 131 dssdev->name); 131 - return 0; 132 + continue; 132 133 } 133 134 134 135 encoder = omap_encoder_init(dev, dssdev); ··· 156 157 157 158 drm_mode_connector_attach_encoder(connector, encoder); 158 159 160 + /* 161 + * if we have reached the limit of the crtcs we are allowed to 162 + * create, let's not try to look for a crtc for this 163 + * panel/encoder and onwards, we will, of course, populate the 164 + * the possible_crtcs field for all the encoders with the final 165 + * set of crtcs we create 166 + */ 167 + if (id == num_crtcs) 168 + continue; 169 + 170 + /* 171 + * get the recommended DISPC channel for this encoder. For now, 172 + * we only try to get create a crtc out of the recommended, the 173 + * other possible channels to which the encoder can connect are 174 + * not considered. 175 + */ 176 + channel = dssdev->output->dispc_channel; 177 + 178 + /* 179 + * if this channel hasn't already been taken by a previously 180 + * allocated crtc, we create a new crtc for it 181 + */ 182 + if (!channel_used(dev, channel)) { 183 + struct drm_plane *plane; 184 + struct drm_crtc *crtc; 185 + 186 + plane = omap_plane_init(dev, id, true); 187 + crtc = omap_crtc_init(dev, plane, channel, id); 188 + 189 + BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); 190 + priv->crtcs[id] = crtc; 191 + priv->num_crtcs++; 192 + 193 + priv->planes[id] = plane; 194 + priv->num_planes++; 195 + 196 + id++; 197 + } 198 + } 199 + 200 + /* 201 + * we have allocated crtcs according to the need of the panels/encoders, 202 + * adding more crtcs here if needed 203 + */ 204 + for (; id < num_crtcs; id++) { 205 + 206 + /* find a free manager for this crtc */ 207 + for (i = 0; i < num_mgrs; i++) { 208 + if (!channel_used(dev, i)) { 209 + struct drm_plane *plane; 210 + struct drm_crtc *crtc; 211 + 212 + plane = omap_plane_init(dev, id, true); 213 + crtc = omap_crtc_init(dev, plane, i, id); 214 + 215 + BUG_ON(priv->num_crtcs >= 216 + ARRAY_SIZE(priv->crtcs)); 217 + 218 + priv->crtcs[id] = crtc; 219 + priv->num_crtcs++; 220 + 221 + priv->planes[id] = plane; 222 + priv->num_planes++; 223 + 224 + break; 225 + } else { 226 + continue; 227 + } 228 + } 229 + 230 + if (i == num_mgrs) { 231 + /* this shouldn't really happen */ 232 + dev_err(dev->dev, "no managers left for crtc\n"); 233 + return -ENOMEM; 234 + } 235 + } 236 + 237 + /* 238 + * Create normal planes for the remaining overlays: 239 + */ 240 + for (; id < num_ovls; id++) { 241 + struct drm_plane *plane = omap_plane_init(dev, id, false); 242 + 243 + BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); 244 + priv->planes[priv->num_planes++] = plane; 245 + } 246 + 247 + for (i = 0; i < priv->num_encoders; i++) { 248 + struct drm_encoder *encoder = priv->encoders[i]; 249 + struct omap_dss_device *dssdev = 250 + omap_encoder_get_dssdev(encoder); 251 + 159 252 /* figure out which crtc's we can connect the encoder to: */ 160 253 encoder->possible_crtcs = 0; 161 254 for (id = 0; id < priv->num_crtcs; id++) { 162 - enum omap_dss_output_id supported_outputs = 163 - dss_feat_get_supported_outputs(pipe2chan(id)); 255 + struct drm_crtc *crtc = priv->crtcs[id]; 256 + enum omap_channel crtc_channel; 257 + enum omap_dss_output_id supported_outputs; 258 + 259 + crtc_channel = omap_crtc_channel(crtc); 260 + supported_outputs = 261 + dss_feat_get_supported_outputs(crtc_channel); 262 + 164 263 if (supported_outputs & dssdev->output->id) 165 264 encoder->possible_crtcs |= (1 << id); 166 265 } 167 266 } 267 + 268 + DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", 269 + priv->num_planes, priv->num_crtcs, priv->num_encoders, 270 + priv->num_connectors); 168 271 169 272 dev->mode_config.min_width = 32; 170 273 dev->mode_config.min_height = 32; ··· 404 303 return ret; 405 304 } 406 305 407 - struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { 306 + static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { 408 307 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH), 409 308 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 410 309 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH), ··· 668 567 }; 669 568 #endif 670 569 671 - struct platform_driver pdev = { 570 + static struct platform_driver pdev = { 672 571 .driver = { 673 572 .name = DRIVER_NAME, 674 573 .owner = THIS_MODULE,
+4 -34
drivers/gpu/drm/omapdrm/omap_drv.h
··· 139 139 int omap_gem_resume(struct device *dev); 140 140 #endif 141 141 142 - int omap_irq_enable_vblank(struct drm_device *dev, int crtc); 143 - void omap_irq_disable_vblank(struct drm_device *dev, int crtc); 142 + int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id); 143 + void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id); 144 144 irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); 145 145 void omap_irq_preinstall(struct drm_device *dev); 146 146 int omap_irq_postinstall(struct drm_device *dev); ··· 271 271 return ALIGN(pitch, 8 * bytespp); 272 272 } 273 273 274 - static inline enum omap_channel pipe2chan(int pipe) 275 - { 276 - int num_mgrs = dss_feat_get_num_mgrs(); 277 - 278 - /* 279 - * We usually don't want to create a CRTC for each manager, 280 - * at least not until we have a way to expose private planes 281 - * to userspace. Otherwise there would not be enough video 282 - * pipes left for drm planes. The higher #'d managers tend 283 - * to have more features so start in reverse order. 284 - */ 285 - return num_mgrs - pipe - 1; 286 - } 287 - 288 274 /* map crtc to vblank mask */ 289 - static inline uint32_t pipe2vbl(int crtc) 290 - { 291 - enum omap_channel channel = pipe2chan(crtc); 292 - return dispc_mgr_get_vsync_irq(channel); 293 - } 294 - 295 - static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc) 296 - { 297 - struct omap_drm_private *priv = dev->dev_private; 298 - int i; 299 - 300 - for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++) 301 - if (priv->crtcs[i] == crtc) 302 - return i; 303 - 304 - BUG(); /* bogus CRTC ptr */ 305 - return -1; 306 - } 275 + uint32_t pipe2vbl(struct drm_crtc *crtc); 276 + struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder); 307 277 308 278 /* should these be made into common util helpers? 309 279 */
+22 -2
drivers/gpu/drm/omapdrm/omap_encoder.c
··· 41 41 struct omap_dss_device *dssdev; 42 42 }; 43 43 44 + struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder) 45 + { 46 + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 47 + 48 + return omap_encoder->dssdev; 49 + } 50 + 44 51 static void omap_encoder_destroy(struct drm_encoder *encoder) 45 52 { 46 53 struct omap_encoder *omap_encoder = to_omap_encoder(encoder); ··· 135 128 136 129 dssdev->output->manager = mgr; 137 130 138 - ret = dssdrv->check_timings(dssdev, timings); 131 + if (dssdrv->check_timings) { 132 + ret = dssdrv->check_timings(dssdev, timings); 133 + } else { 134 + struct omap_video_timings t = {0}; 135 + 136 + dssdrv->get_timings(dssdev, &t); 137 + 138 + if (memcmp(timings, &t, sizeof(struct omap_video_timings))) 139 + ret = -EINVAL; 140 + else 141 + ret = 0; 142 + } 143 + 139 144 if (ret) { 140 145 dev_err(dev->dev, "could not set timings: %d\n", ret); 141 146 return ret; 142 147 } 143 148 144 - dssdrv->set_timings(dssdev, timings); 149 + if (dssdrv->set_timings) 150 + dssdrv->set_timings(dssdev, timings); 145 151 146 152 return 0; 147 153 }
+1 -1
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
··· 178 178 return omap_gem_mmap_obj(obj, vma); 179 179 } 180 180 181 - struct dma_buf_ops omap_dmabuf_ops = { 181 + static struct dma_buf_ops omap_dmabuf_ops = { 182 182 .map_dma_buf = omap_gem_map_dma_buf, 183 183 .unmap_dma_buf = omap_gem_unmap_dma_buf, 184 184 .release = omap_gem_dmabuf_release,
+11 -6
drivers/gpu/drm/omapdrm/omap_irq.c
··· 130 130 * Zero on success, appropriate errno if the given @crtc's vblank 131 131 * interrupt cannot be enabled. 132 132 */ 133 - int omap_irq_enable_vblank(struct drm_device *dev, int crtc) 133 + int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id) 134 134 { 135 135 struct omap_drm_private *priv = dev->dev_private; 136 + struct drm_crtc *crtc = priv->crtcs[crtc_id]; 136 137 unsigned long flags; 137 138 138 - DBG("dev=%p, crtc=%d", dev, crtc); 139 + DBG("dev=%p, crtc=%d", dev, crtc_id); 139 140 140 141 dispc_runtime_get(); 141 142 spin_lock_irqsave(&list_lock, flags); ··· 157 156 * a hardware vblank counter, this routine should be a no-op, since 158 157 * interrupts will have to stay on to keep the count accurate. 159 158 */ 160 - void omap_irq_disable_vblank(struct drm_device *dev, int crtc) 159 + void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id) 161 160 { 162 161 struct omap_drm_private *priv = dev->dev_private; 162 + struct drm_crtc *crtc = priv->crtcs[crtc_id]; 163 163 unsigned long flags; 164 164 165 - DBG("dev=%p, crtc=%d", dev, crtc); 165 + DBG("dev=%p, crtc=%d", dev, crtc_id); 166 166 167 167 dispc_runtime_get(); 168 168 spin_lock_irqsave(&list_lock, flags); ··· 188 186 189 187 VERB("irqs: %08x", irqstatus); 190 188 191 - for (id = 0; id < priv->num_crtcs; id++) 192 - if (irqstatus & pipe2vbl(id)) 189 + for (id = 0; id < priv->num_crtcs; id++) { 190 + struct drm_crtc *crtc = priv->crtcs[id]; 191 + 192 + if (irqstatus & pipe2vbl(crtc)) 193 193 drm_handle_vblank(dev, id); 194 + } 194 195 195 196 spin_lock_irqsave(&list_lock, flags); 196 197 list_for_each_entry_safe(handler, n, &priv->irq_list, node) {
+6
drivers/gpu/drm/omapdrm/omap_plane.c
··· 247 247 { 248 248 struct omap_plane *omap_plane = to_omap_plane(plane); 249 249 omap_plane->enabled = true; 250 + 251 + if (plane->fb) 252 + drm_framebuffer_unreference(plane->fb); 253 + 254 + drm_framebuffer_reference(fb); 255 + 250 256 return omap_plane_mode_set(plane, crtc, fb, 251 257 crtc_x, crtc_y, crtc_w, crtc_h, 252 258 src_x, src_y, src_w, src_h,
+16 -4
drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
··· 242 242 return 0; 243 243 } 244 244 245 - static int nec_8048_spi_suspend(struct spi_device *spi, pm_message_t mesg) 245 + #ifdef CONFIG_PM_SLEEP 246 + 247 + static int nec_8048_spi_suspend(struct device *dev) 246 248 { 249 + struct spi_device *spi = to_spi_device(dev); 250 + 247 251 nec_8048_spi_send(spi, 2, 0x01); 248 252 mdelay(40); 249 253 250 254 return 0; 251 255 } 252 256 253 - static int nec_8048_spi_resume(struct spi_device *spi) 257 + static int nec_8048_spi_resume(struct device *dev) 254 258 { 259 + struct spi_device *spi = to_spi_device(dev); 260 + 255 261 /* reinitialize the panel */ 256 262 spi_setup(spi); 257 263 nec_8048_spi_send(spi, 2, 0x00); ··· 266 260 return 0; 267 261 } 268 262 263 + static SIMPLE_DEV_PM_OPS(nec_8048_spi_pm_ops, nec_8048_spi_suspend, 264 + nec_8048_spi_resume); 265 + #define NEC_8048_SPI_PM_OPS (&nec_8048_spi_pm_ops) 266 + #else 267 + #define NEC_8048_SPI_PM_OPS NULL 268 + #endif 269 + 269 270 static struct spi_driver nec_8048_spi_driver = { 270 271 .probe = nec_8048_spi_probe, 271 272 .remove = nec_8048_spi_remove, 272 - .suspend = nec_8048_spi_suspend, 273 - .resume = nec_8048_spi_resume, 274 273 .driver = { 275 274 .name = "nec_8048_spi", 276 275 .owner = THIS_MODULE, 276 + .pm = NEC_8048_SPI_PM_OPS, 277 277 }, 278 278 }; 279 279
+29 -269
drivers/video/omap2/displays/panel-taal.c
··· 54 54 55 55 static int taal_panel_reset(struct omap_dss_device *dssdev); 56 56 57 - /** 58 - * struct panel_config - panel configuration 59 - * @name: panel name 60 - * @type: panel type 61 - * @timings: panel resolution 62 - * @sleep: various panel specific delays, passed to msleep() if non-zero 63 - * @reset_sequence: reset sequence timings, passed to udelay() if non-zero 64 - * @regulators: array of panel regulators 65 - * @num_regulators: number of regulators in the array 66 - */ 67 - struct panel_config { 68 - const char *name; 69 - int type; 70 - 71 - struct omap_video_timings timings; 72 - 73 - struct { 74 - unsigned int sleep_in; 75 - unsigned int sleep_out; 76 - unsigned int hw_reset; 77 - unsigned int enable_te; 78 - } sleep; 79 - 80 - struct { 81 - unsigned int high; 82 - unsigned int low; 83 - } reset_sequence; 84 - 85 - }; 86 - 87 - enum { 88 - PANEL_TAAL, 89 - }; 90 - 91 - static struct panel_config panel_configs[] = { 92 - { 93 - .name = "taal", 94 - .type = PANEL_TAAL, 95 - .timings = { 96 - .x_res = 864, 97 - .y_res = 480, 98 - }, 99 - .sleep = { 100 - .sleep_in = 5, 101 - .sleep_out = 5, 102 - .hw_reset = 5, 103 - .enable_te = 100, /* possible panel bug */ 104 - }, 105 - .reset_sequence = { 106 - .high = 10, 107 - .low = 10, 108 - }, 109 - }, 110 - }; 111 - 112 57 struct taal_data { 113 58 struct mutex lock; 114 59 ··· 66 121 67 122 struct omap_dss_device *dssdev; 68 123 69 - /* panel specific HW info */ 70 - struct panel_config *panel_config; 71 - 72 124 /* panel HW configuration from DT or platform data */ 73 125 int reset_gpio; 74 126 int ext_te_gpio; ··· 76 134 77 135 /* runtime variables */ 78 136 bool enabled; 79 - u8 rotate; 80 - bool mirror; 81 137 82 138 bool te_enabled; 83 139 ··· 161 221 162 222 hw_guard_start(td, 120); 163 223 164 - if (td->panel_config->sleep.sleep_in) 165 - msleep(td->panel_config->sleep.sleep_in); 224 + msleep(5); 166 225 167 226 return 0; 168 227 } ··· 178 239 179 240 hw_guard_start(td, 120); 180 241 181 - if (td->panel_config->sleep.sleep_out) 182 - msleep(td->panel_config->sleep.sleep_out); 242 + msleep(5); 183 243 184 244 return 0; 185 245 } ··· 198 260 return r; 199 261 200 262 return 0; 201 - } 202 - 203 - static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror) 204 - { 205 - int r; 206 - u8 mode; 207 - int b5, b6, b7; 208 - 209 - r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode); 210 - if (r) 211 - return r; 212 - 213 - switch (rotate) { 214 - default: 215 - case 0: 216 - b7 = 0; 217 - b6 = 0; 218 - b5 = 0; 219 - break; 220 - case 1: 221 - b7 = 0; 222 - b6 = 1; 223 - b5 = 1; 224 - break; 225 - case 2: 226 - b7 = 1; 227 - b6 = 1; 228 - b5 = 0; 229 - break; 230 - case 3: 231 - b7 = 1; 232 - b6 = 0; 233 - b5 = 1; 234 - break; 235 - } 236 - 237 - if (mirror) 238 - b6 = !b6; 239 - 240 - mode &= ~((1<<7) | (1<<6) | (1<<5)); 241 - mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); 242 - 243 - return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode); 244 263 } 245 264 246 265 static int taal_set_update_window(struct taal_data *td, ··· 410 515 static void taal_get_resolution(struct omap_dss_device *dssdev, 411 516 u16 *xres, u16 *yres) 412 517 { 413 - struct taal_data *td = dev_get_drvdata(&dssdev->dev); 414 - 415 - if (td->rotate == 0 || td->rotate == 2) { 416 - *xres = dssdev->panel.timings.x_res; 417 - *yres = dssdev->panel.timings.y_res; 418 - } else { 419 - *yres = dssdev->panel.timings.x_res; 420 - *xres = dssdev->panel.timings.y_res; 421 - } 518 + *xres = dssdev->panel.timings.x_res; 519 + *yres = dssdev->panel.timings.y_res; 422 520 } 423 521 424 522 static ssize_t taal_num_errors_show(struct device *dev, ··· 733 845 return; 734 846 735 847 gpio_set_value(td->reset_gpio, 1); 736 - if (td->panel_config->reset_sequence.high) 737 - udelay(td->panel_config->reset_sequence.high); 848 + udelay(10); 738 849 /* reset the panel */ 739 850 gpio_set_value(td->reset_gpio, 0); 740 851 /* assert reset */ 741 - if (td->panel_config->reset_sequence.low) 742 - udelay(td->panel_config->reset_sequence.low); 852 + udelay(10); 743 853 gpio_set_value(td->reset_gpio, 1); 744 854 /* wait after releasing reset */ 745 - if (td->panel_config->sleep.hw_reset) 746 - msleep(td->panel_config->sleep.hw_reset); 855 + msleep(5); 747 856 } 748 857 749 858 static void taal_probe_pdata(struct taal_data *td, ··· 766 881 struct backlight_properties props; 767 882 struct taal_data *td; 768 883 struct backlight_device *bldev = NULL; 769 - int r, i; 770 - const char *panel_name; 884 + int r; 771 885 772 886 dev_dbg(&dssdev->dev, "probe\n"); 773 887 ··· 781 897 const struct nokia_dsi_panel_data *pdata = dssdev->data; 782 898 783 899 taal_probe_pdata(td, pdata); 784 - 785 - panel_name = pdata->name; 786 900 } else { 787 901 return -ENODEV; 788 902 } 789 903 790 - if (panel_name == NULL) 791 - return -EINVAL; 792 - 793 - for (i = 0; i < ARRAY_SIZE(panel_configs); i++) { 794 - if (strcmp(panel_name, panel_configs[i].name) == 0) { 795 - td->panel_config = &panel_configs[i]; 796 - break; 797 - } 798 - } 799 - 800 - if (!td->panel_config) 801 - return -EINVAL; 802 - 803 - dssdev->panel.timings = td->panel_config->timings; 904 + dssdev->panel.timings.x_res = 864; 905 + dssdev->panel.timings.y_res = 480; 906 + dssdev->panel.timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000); 804 907 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; 805 908 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 806 909 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; ··· 920 1049 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 921 1050 u8 id1, id2, id3; 922 1051 int r; 1052 + struct omap_dss_dsi_config dsi_config = { 1053 + .mode = OMAP_DSS_DSI_CMD_MODE, 1054 + .pixel_format = OMAP_DSS_DSI_FMT_RGB888, 1055 + .timings = &dssdev->panel.timings, 1056 + .hs_clk_min = 150000000, 1057 + .hs_clk_max = 300000000, 1058 + .lp_clk_min = 7000000, 1059 + .lp_clk_max = 10000000, 1060 + }; 923 1061 924 1062 r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); 925 1063 if (r) { ··· 936 1056 goto err0; 937 1057 }; 938 1058 939 - omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res, 940 - dssdev->panel.timings.y_res); 941 - omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888); 942 - omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE); 943 - 944 - r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000); 1059 + r = omapdss_dsi_set_config(dssdev, &dsi_config); 945 1060 if (r) { 946 - dev_err(&dssdev->dev, "failed to set HS and LP clocks\n"); 1061 + dev_err(&dssdev->dev, "failed to configure DSI\n"); 947 1062 goto err0; 948 1063 } 949 1064 ··· 961 1086 goto err; 962 1087 963 1088 /* on early Taal revisions CABC is broken */ 964 - if (td->panel_config->type == PANEL_TAAL && 965 - (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) 1089 + if (id2 == 0x00 || id2 == 0xff || id2 == 0x81) 966 1090 td->cabc_broken = true; 967 1091 968 1092 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff); ··· 975 1101 976 1102 r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT, 977 1103 MIPI_DCS_PIXEL_FMT_24BIT); 978 - if (r) 979 - goto err; 980 - 981 - r = taal_set_addr_mode(td, td->rotate, td->mirror); 982 1104 if (r) 983 1105 goto err; 984 1106 ··· 999 1129 td->enabled = 1; 1000 1130 1001 1131 if (!td->intro_printed) { 1002 - dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n", 1003 - td->panel_config->name, id1, id2, id3); 1132 + dev_info(&dssdev->dev, "panel revision %02x.%02x.%02x\n", 1133 + id1, id2, id3); 1004 1134 if (td->cabc_broken) 1005 1135 dev_info(&dssdev->dev, 1006 1136 "old Taal version, CABC disabled\n"); ··· 1181 1311 1182 1312 /* XXX no need to send this every frame, but dsi break if not done */ 1183 1313 r = taal_set_update_window(td, 0, 0, 1184 - td->panel_config->timings.x_res, 1185 - td->panel_config->timings.y_res); 1314 + dssdev->panel.timings.x_res, 1315 + dssdev->panel.timings.y_res); 1186 1316 if (r) 1187 1317 goto err; 1188 1318 ··· 1235 1365 if (!gpio_is_valid(td->ext_te_gpio)) 1236 1366 omapdss_dsi_enable_te(dssdev, enable); 1237 1367 1238 - if (td->panel_config->sleep.enable_te) 1239 - msleep(td->panel_config->sleep.enable_te); 1368 + /* possible panel bug */ 1369 + msleep(100); 1240 1370 1241 1371 return r; 1242 1372 } ··· 1284 1414 1285 1415 mutex_lock(&td->lock); 1286 1416 r = td->te_enabled; 1287 - mutex_unlock(&td->lock); 1288 - 1289 - return r; 1290 - } 1291 - 1292 - static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) 1293 - { 1294 - struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1295 - u16 dw, dh; 1296 - int r; 1297 - 1298 - dev_dbg(&dssdev->dev, "rotate %d\n", rotate); 1299 - 1300 - mutex_lock(&td->lock); 1301 - 1302 - if (td->rotate == rotate) 1303 - goto end; 1304 - 1305 - dsi_bus_lock(dssdev); 1306 - 1307 - if (td->enabled) { 1308 - r = taal_wake_up(dssdev); 1309 - if (r) 1310 - goto err; 1311 - 1312 - r = taal_set_addr_mode(td, rotate, td->mirror); 1313 - if (r) 1314 - goto err; 1315 - } 1316 - 1317 - if (rotate == 0 || rotate == 2) { 1318 - dw = dssdev->panel.timings.x_res; 1319 - dh = dssdev->panel.timings.y_res; 1320 - } else { 1321 - dw = dssdev->panel.timings.y_res; 1322 - dh = dssdev->panel.timings.x_res; 1323 - } 1324 - 1325 - omapdss_dsi_set_size(dssdev, dw, dh); 1326 - 1327 - td->rotate = rotate; 1328 - 1329 - dsi_bus_unlock(dssdev); 1330 - end: 1331 - mutex_unlock(&td->lock); 1332 - return 0; 1333 - err: 1334 - dsi_bus_unlock(dssdev); 1335 - mutex_unlock(&td->lock); 1336 - return r; 1337 - } 1338 - 1339 - static u8 taal_get_rotate(struct omap_dss_device *dssdev) 1340 - { 1341 - struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1342 - int r; 1343 - 1344 - mutex_lock(&td->lock); 1345 - r = td->rotate; 1346 - mutex_unlock(&td->lock); 1347 - 1348 - return r; 1349 - } 1350 - 1351 - static int taal_mirror(struct omap_dss_device *dssdev, bool enable) 1352 - { 1353 - struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1354 - int r; 1355 - 1356 - dev_dbg(&dssdev->dev, "mirror %d\n", enable); 1357 - 1358 - mutex_lock(&td->lock); 1359 - 1360 - if (td->mirror == enable) 1361 - goto end; 1362 - 1363 - dsi_bus_lock(dssdev); 1364 - if (td->enabled) { 1365 - r = taal_wake_up(dssdev); 1366 - if (r) 1367 - goto err; 1368 - 1369 - r = taal_set_addr_mode(td, td->rotate, enable); 1370 - if (r) 1371 - goto err; 1372 - } 1373 - 1374 - td->mirror = enable; 1375 - 1376 - dsi_bus_unlock(dssdev); 1377 - end: 1378 - mutex_unlock(&td->lock); 1379 - return 0; 1380 - err: 1381 - dsi_bus_unlock(dssdev); 1382 - mutex_unlock(&td->lock); 1383 - return r; 1384 - } 1385 - 1386 - static bool taal_get_mirror(struct omap_dss_device *dssdev) 1387 - { 1388 - struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1389 - int r; 1390 - 1391 - mutex_lock(&td->lock); 1392 - r = td->mirror; 1393 1417 mutex_unlock(&td->lock); 1394 1418 1395 1419 return r; ··· 1522 1758 .enable_te = taal_enable_te, 1523 1759 .get_te = taal_get_te, 1524 1760 1525 - .set_rotate = taal_rotate, 1526 - .get_rotate = taal_get_rotate, 1527 - .set_mirror = taal_mirror, 1528 - .get_mirror = taal_get_mirror, 1529 1761 .run_test = taal_run_test, 1530 1762 .memory_read = taal_memory_read, 1531 1763
+11 -4
drivers/video/omap2/dss/apply.c
··· 435 435 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) 436 436 { 437 437 unsigned long timeout = msecs_to_jiffies(500); 438 - struct omap_dss_device *dssdev = mgr->get_device(mgr); 439 438 u32 irq; 440 439 int r; 440 + 441 + if (mgr->output == NULL) 442 + return -ENODEV; 441 443 442 444 r = dispc_runtime_get(); 443 445 if (r) 444 446 return r; 445 447 446 - if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) 448 + switch (mgr->output->id) { 449 + case OMAP_DSS_OUTPUT_VENC: 447 450 irq = DISPC_IRQ_EVSYNC_ODD; 448 - else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) 451 + break; 452 + case OMAP_DSS_OUTPUT_HDMI: 449 453 irq = DISPC_IRQ_EVSYNC_EVEN; 450 - else 454 + break; 455 + default: 451 456 irq = dispc_mgr_get_vsync_irq(mgr->id); 457 + break; 458 + } 452 459 453 460 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 454 461
+1 -4
drivers/video/omap2/dss/core.c
··· 181 181 d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, 182 182 write, &dss_debug_fops); 183 183 184 - if (IS_ERR(d)) 185 - return PTR_ERR(d); 186 - 187 - return 0; 184 + return PTR_RET(d); 188 185 } 189 186 #else /* CONFIG_OMAP2_DSS_DEBUGFS */ 190 187 static inline int dss_initialize_debugfs(void)
+115 -63
drivers/video/omap2/dss/dispc.c
··· 69 69 u8 mgr_height_start; 70 70 u16 mgr_width_max; 71 71 u16 mgr_height_max; 72 + unsigned long max_lcd_pclk; 73 + unsigned long max_tv_pclk; 72 74 int (*calc_scaling) (unsigned long pclk, unsigned long lclk, 73 75 const struct omap_video_timings *mgr_timings, 74 76 u16 width, u16 height, u16 out_width, u16 out_height, ··· 87 85 88 86 /* no DISPC_IRQ_FRAMEDONETV on this SoC */ 89 87 bool no_framedone_tv:1; 88 + 89 + /* revert to the OMAP4 mechanism of DISPC Smart Standby operation */ 90 + bool mstandby_workaround:1; 90 91 }; 91 92 92 93 #define DISPC_MAX_NR_FIFOS 5 ··· 101 96 int ctx_loss_cnt; 102 97 103 98 int irq; 99 + 100 + unsigned long core_clk_rate; 104 101 105 102 u32 fifo_size[DISPC_MAX_NR_FIFOS]; 106 103 /* maps which plane is using a fifo. fifo-id -> plane-id */ ··· 1591 1584 } 1592 1585 1593 1586 static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1587 + enum omap_dss_rotation_type rotation_type, 1594 1588 bool mirroring, enum omap_color_mode color_mode) 1595 1589 { 1596 1590 bool row_repeat = false; ··· 1642 1634 if (dss_has_feature(FEAT_ROWREPEATENABLE)) 1643 1635 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1644 1636 row_repeat ? 1 : 0, 18, 18); 1637 + 1638 + if (color_mode == OMAP_DSS_COLOR_NV12) { 1639 + bool doublestride = (rotation_type == OMAP_DSS_ROT_TILER) && 1640 + (rotation == OMAP_DSS_ROT_0 || 1641 + rotation == OMAP_DSS_ROT_180); 1642 + /* DOUBLESTRIDE */ 1643 + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), doublestride, 22, 22); 1644 + } 1645 + 1645 1646 } 1646 1647 1647 1648 static int color_mode_to_bpp(enum omap_color_mode color_mode) ··· 2529 2512 dispc_ovl_set_vid_color_conv(plane, cconv); 2530 2513 } 2531 2514 2532 - dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode); 2515 + dispc_ovl_set_rotation_attrs(plane, rotation, rotation_type, mirror, 2516 + color_mode); 2533 2517 2534 2518 dispc_ovl_set_zorder(plane, caps, zorder); 2535 2519 dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha); ··· 2841 2823 return true; 2842 2824 } 2843 2825 2826 + static bool _dispc_mgr_pclk_ok(enum omap_channel channel, 2827 + unsigned long pclk) 2828 + { 2829 + if (dss_mgr_is_lcd(channel)) 2830 + return pclk <= dispc.feat->max_lcd_pclk ? true : false; 2831 + else 2832 + return pclk <= dispc.feat->max_tv_pclk ? true : false; 2833 + } 2834 + 2844 2835 bool dispc_mgr_timings_ok(enum omap_channel channel, 2845 2836 const struct omap_video_timings *timings) 2846 2837 { ··· 2857 2830 2858 2831 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); 2859 2832 2860 - if (dss_mgr_is_lcd(channel)) 2861 - timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, 2862 - timings->hfp, timings->hbp, 2863 - timings->vsw, timings->vfp, 2864 - timings->vbp); 2833 + timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixel_clock * 1000); 2834 + 2835 + if (dss_mgr_is_lcd(channel)) { 2836 + timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp, 2837 + timings->hbp, timings->vsw, timings->vfp, 2838 + timings->vbp); 2839 + } 2865 2840 2866 2841 return timings_ok; 2867 2842 } ··· 2980 2951 2981 2952 dispc_write_reg(DISPC_DIVISORo(channel), 2982 2953 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2954 + 2955 + if (dss_has_feature(FEAT_CORE_CLK_DIV) == false && 2956 + channel == OMAP_DSS_CHANNEL_LCD) 2957 + dispc.core_clk_rate = dispc_fclk_rate() / lck_div; 2983 2958 } 2984 2959 2985 2960 static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div, ··· 3089 3056 3090 3057 unsigned long dispc_core_clk_rate(void) 3091 3058 { 3092 - int lcd; 3093 - unsigned long fclk = dispc_fclk_rate(); 3094 - 3095 - if (dss_has_feature(FEAT_CORE_CLK_DIV)) 3096 - lcd = REG_GET(DISPC_DIVISOR, 23, 16); 3097 - else 3098 - lcd = REG_GET(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD), 23, 16); 3099 - 3100 - return fclk / lcd; 3059 + return dispc.core_clk_rate; 3101 3060 } 3102 3061 3103 3062 static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) ··· 3338 3313 #undef DUMPREG 3339 3314 } 3340 3315 3341 - /* with fck as input clock rate, find dispc dividers that produce req_pck */ 3342 - void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck, 3343 - struct dispc_clock_info *cinfo) 3344 - { 3345 - u16 pcd_min, pcd_max; 3346 - unsigned long best_pck; 3347 - u16 best_ld, cur_ld; 3348 - u16 best_pd, cur_pd; 3349 - 3350 - pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); 3351 - pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); 3352 - 3353 - best_pck = 0; 3354 - best_ld = 0; 3355 - best_pd = 0; 3356 - 3357 - for (cur_ld = 1; cur_ld <= 255; ++cur_ld) { 3358 - unsigned long lck = fck / cur_ld; 3359 - 3360 - for (cur_pd = pcd_min; cur_pd <= pcd_max; ++cur_pd) { 3361 - unsigned long pck = lck / cur_pd; 3362 - long old_delta = abs(best_pck - req_pck); 3363 - long new_delta = abs(pck - req_pck); 3364 - 3365 - if (best_pck == 0 || new_delta < old_delta) { 3366 - best_pck = pck; 3367 - best_ld = cur_ld; 3368 - best_pd = cur_pd; 3369 - 3370 - if (pck == req_pck) 3371 - goto found; 3372 - } 3373 - 3374 - if (pck < req_pck) 3375 - break; 3376 - } 3377 - 3378 - if (lck / pcd_min < req_pck) 3379 - break; 3380 - } 3381 - 3382 - found: 3383 - cinfo->lck_div = best_ld; 3384 - cinfo->pck_div = best_pd; 3385 - cinfo->lck = fck / cinfo->lck_div; 3386 - cinfo->pck = cinfo->lck / cinfo->pck_div; 3387 - } 3388 - 3389 3316 /* calculate clock rates using dividers in cinfo */ 3390 3317 int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 3391 3318 struct dispc_clock_info *cinfo) ··· 3351 3374 cinfo->pck = cinfo->lck / cinfo->pck_div; 3352 3375 3353 3376 return 0; 3377 + } 3378 + 3379 + bool dispc_div_calc(unsigned long dispc, 3380 + unsigned long pck_min, unsigned long pck_max, 3381 + dispc_div_calc_func func, void *data) 3382 + { 3383 + int lckd, lckd_start, lckd_stop; 3384 + int pckd, pckd_start, pckd_stop; 3385 + unsigned long pck, lck; 3386 + unsigned long lck_max; 3387 + unsigned long pckd_hw_min, pckd_hw_max; 3388 + unsigned min_fck_per_pck; 3389 + unsigned long fck; 3390 + 3391 + #ifdef CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK 3392 + min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 3393 + #else 3394 + min_fck_per_pck = 0; 3395 + #endif 3396 + 3397 + pckd_hw_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); 3398 + pckd_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); 3399 + 3400 + lck_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 3401 + 3402 + pck_min = pck_min ? pck_min : 1; 3403 + pck_max = pck_max ? pck_max : ULONG_MAX; 3404 + 3405 + lckd_start = max(DIV_ROUND_UP(dispc, lck_max), 1ul); 3406 + lckd_stop = min(dispc / pck_min, 255ul); 3407 + 3408 + for (lckd = lckd_start; lckd <= lckd_stop; ++lckd) { 3409 + lck = dispc / lckd; 3410 + 3411 + pckd_start = max(DIV_ROUND_UP(lck, pck_max), pckd_hw_min); 3412 + pckd_stop = min(lck / pck_min, pckd_hw_max); 3413 + 3414 + for (pckd = pckd_start; pckd <= pckd_stop; ++pckd) { 3415 + pck = lck / pckd; 3416 + 3417 + /* 3418 + * For OMAP2/3 the DISPC fclk is the same as LCD's logic 3419 + * clock, which means we're configuring DISPC fclk here 3420 + * also. Thus we need to use the calculated lck. For 3421 + * OMAP4+ the DISPC fclk is a separate clock. 3422 + */ 3423 + if (dss_has_feature(FEAT_CORE_CLK_DIV)) 3424 + fck = dispc_core_clk_rate(); 3425 + else 3426 + fck = lck; 3427 + 3428 + if (fck < pck * min_fck_per_pck) 3429 + continue; 3430 + 3431 + if (func(lckd, pckd, lck, pck, data)) 3432 + return true; 3433 + } 3434 + } 3435 + 3436 + return false; 3354 3437 } 3355 3438 3356 3439 void dispc_mgr_set_clock_div(enum omap_channel channel, ··· 3488 3451 l = FLD_MOD(l, 1, 0, 0); 3489 3452 l = FLD_MOD(l, 1, 23, 16); 3490 3453 dispc_write_reg(DISPC_DIVISOR, l); 3454 + 3455 + dispc.core_clk_rate = dispc_fclk_rate(); 3491 3456 } 3492 3457 3493 3458 /* FUNCGATED */ ··· 3505 3466 dispc_configure_burst_sizes(); 3506 3467 3507 3468 dispc_ovl_enable_zorder_planes(); 3469 + 3470 + if (dispc.feat->mstandby_workaround) 3471 + REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0); 3508 3472 } 3509 3473 3510 3474 static const struct dispc_features omap24xx_dispc_feats __initconst = { ··· 3521 3479 .mgr_height_start = 26, 3522 3480 .mgr_width_max = 2048, 3523 3481 .mgr_height_max = 2048, 3482 + .max_lcd_pclk = 66500000, 3524 3483 .calc_scaling = dispc_ovl_calc_scaling_24xx, 3525 3484 .calc_core_clk = calc_core_clk_24xx, 3526 3485 .num_fifos = 3, ··· 3539 3496 .mgr_height_start = 26, 3540 3497 .mgr_width_max = 2048, 3541 3498 .mgr_height_max = 2048, 3499 + .max_lcd_pclk = 173000000, 3500 + .max_tv_pclk = 59000000, 3542 3501 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3543 3502 .calc_core_clk = calc_core_clk_34xx, 3544 3503 .num_fifos = 3, ··· 3558 3513 .mgr_height_start = 26, 3559 3514 .mgr_width_max = 2048, 3560 3515 .mgr_height_max = 2048, 3516 + .max_lcd_pclk = 173000000, 3517 + .max_tv_pclk = 59000000, 3561 3518 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3562 3519 .calc_core_clk = calc_core_clk_34xx, 3563 3520 .num_fifos = 3, ··· 3577 3530 .mgr_height_start = 26, 3578 3531 .mgr_width_max = 2048, 3579 3532 .mgr_height_max = 2048, 3533 + .max_lcd_pclk = 170000000, 3534 + .max_tv_pclk = 185625000, 3580 3535 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3581 3536 .calc_core_clk = calc_core_clk_44xx, 3582 3537 .num_fifos = 5, ··· 3596 3547 .mgr_height_start = 27, 3597 3548 .mgr_width_max = 4096, 3598 3549 .mgr_height_max = 4096, 3550 + .max_lcd_pclk = 170000000, 3551 + .max_tv_pclk = 186000000, 3599 3552 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3600 3553 .calc_core_clk = calc_core_clk_44xx, 3601 3554 .num_fifos = 5, 3602 3555 .gfx_fifo_workaround = true, 3556 + .mstandby_workaround = true, 3603 3557 }; 3604 3558 3605 3559 static int __init dispc_init_features(struct platform_device *pdev)
+1
drivers/video/omap2/dss/dispc.h
··· 39 39 #define DISPC_GLOBAL_BUFFER 0x0800 40 40 #define DISPC_CONTROL3 0x0848 41 41 #define DISPC_CONFIG3 0x084C 42 + #define DISPC_MSTANDBY_CTRL 0x0858 42 43 43 44 /* DISPC overlay registers */ 44 45 #define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
+255 -87
drivers/video/omap2/dss/dpi.c
··· 63 63 case OMAPDSS_VER_OMAP3630: 64 64 case OMAPDSS_VER_AM35xx: 65 65 return NULL; 66 - default: 67 - break; 68 - } 69 66 70 - switch (channel) { 71 - case OMAP_DSS_CHANNEL_LCD: 72 - return dsi_get_dsidev_from_id(0); 73 - case OMAP_DSS_CHANNEL_LCD2: 74 - return dsi_get_dsidev_from_id(1); 67 + case OMAPDSS_VER_OMAP4430_ES1: 68 + case OMAPDSS_VER_OMAP4430_ES2: 69 + case OMAPDSS_VER_OMAP4: 70 + switch (channel) { 71 + case OMAP_DSS_CHANNEL_LCD: 72 + return dsi_get_dsidev_from_id(0); 73 + case OMAP_DSS_CHANNEL_LCD2: 74 + return dsi_get_dsidev_from_id(1); 75 + default: 76 + return NULL; 77 + } 78 + 79 + case OMAPDSS_VER_OMAP5: 80 + switch (channel) { 81 + case OMAP_DSS_CHANNEL_LCD: 82 + return dsi_get_dsidev_from_id(0); 83 + case OMAP_DSS_CHANNEL_LCD3: 84 + return dsi_get_dsidev_from_id(1); 85 + default: 86 + return NULL; 87 + } 88 + 75 89 default: 76 90 return NULL; 77 91 } ··· 105 91 } 106 92 } 107 93 108 - static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, 109 - unsigned long pck_req, unsigned long *fck, int *lck_div, 110 - int *pck_div) 111 - { 112 - struct omap_overlay_manager *mgr = dssdev->output->manager; 94 + struct dpi_clk_calc_ctx { 95 + struct platform_device *dsidev; 96 + 97 + /* inputs */ 98 + 99 + unsigned long pck_min, pck_max; 100 + 101 + /* outputs */ 102 + 113 103 struct dsi_clock_info dsi_cinfo; 114 - struct dispc_clock_info dispc_cinfo; 115 - int r; 116 - 117 - r = dsi_pll_calc_clock_div_pck(dpi.dsidev, pck_req, &dsi_cinfo, 118 - &dispc_cinfo); 119 - if (r) 120 - return r; 121 - 122 - r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo); 123 - if (r) 124 - return r; 125 - 126 - dss_select_lcd_clk_source(mgr->id, 127 - dpi_get_alt_clk_src(mgr->id)); 128 - 129 - dpi.mgr_config.clock_info = dispc_cinfo; 130 - 131 - *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 132 - *lck_div = dispc_cinfo.lck_div; 133 - *pck_div = dispc_cinfo.pck_div; 134 - 135 - return 0; 136 - } 137 - 138 - static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, 139 - unsigned long pck_req, unsigned long *fck, int *lck_div, 140 - int *pck_div) 141 - { 142 104 struct dss_clock_info dss_cinfo; 143 105 struct dispc_clock_info dispc_cinfo; 106 + }; 107 + 108 + static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, 109 + unsigned long pck, void *data) 110 + { 111 + struct dpi_clk_calc_ctx *ctx = data; 112 + 113 + /* 114 + * Odd dividers give us uneven duty cycle, causing problem when level 115 + * shifted. So skip all odd dividers when the pixel clock is on the 116 + * higher side. 117 + */ 118 + if (ctx->pck_min >= 1000000) { 119 + if (lckd > 1 && lckd % 2 != 0) 120 + return false; 121 + 122 + if (pckd > 1 && pckd % 2 != 0) 123 + return false; 124 + } 125 + 126 + ctx->dispc_cinfo.lck_div = lckd; 127 + ctx->dispc_cinfo.pck_div = pckd; 128 + ctx->dispc_cinfo.lck = lck; 129 + ctx->dispc_cinfo.pck = pck; 130 + 131 + return true; 132 + } 133 + 134 + 135 + static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, 136 + void *data) 137 + { 138 + struct dpi_clk_calc_ctx *ctx = data; 139 + 140 + /* 141 + * Odd dividers give us uneven duty cycle, causing problem when level 142 + * shifted. So skip all odd dividers when the pixel clock is on the 143 + * higher side. 144 + */ 145 + if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 1000000) 146 + return false; 147 + 148 + ctx->dsi_cinfo.regm_dispc = regm_dispc; 149 + ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; 150 + 151 + return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, 152 + dpi_calc_dispc_cb, ctx); 153 + } 154 + 155 + 156 + static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint, 157 + unsigned long pll, 158 + void *data) 159 + { 160 + struct dpi_clk_calc_ctx *ctx = data; 161 + 162 + ctx->dsi_cinfo.regn = regn; 163 + ctx->dsi_cinfo.regm = regm; 164 + ctx->dsi_cinfo.fint = fint; 165 + ctx->dsi_cinfo.clkin4ddr = pll; 166 + 167 + return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->pck_min, 168 + dpi_calc_hsdiv_cb, ctx); 169 + } 170 + 171 + static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) 172 + { 173 + struct dpi_clk_calc_ctx *ctx = data; 174 + 175 + ctx->dss_cinfo.fck = fck; 176 + ctx->dss_cinfo.fck_div = fckd; 177 + 178 + return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, 179 + dpi_calc_dispc_cb, ctx); 180 + } 181 + 182 + static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) 183 + { 184 + unsigned long clkin; 185 + unsigned long pll_min, pll_max; 186 + 187 + clkin = dsi_get_pll_clkin(dpi.dsidev); 188 + 189 + memset(ctx, 0, sizeof(*ctx)); 190 + ctx->dsidev = dpi.dsidev; 191 + ctx->pck_min = pck - 1000; 192 + ctx->pck_max = pck + 1000; 193 + ctx->dsi_cinfo.clkin = clkin; 194 + 195 + pll_min = 0; 196 + pll_max = 0; 197 + 198 + return dsi_pll_calc(dpi.dsidev, clkin, 199 + pll_min, pll_max, 200 + dpi_calc_pll_cb, ctx); 201 + } 202 + 203 + static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) 204 + { 205 + int i; 206 + 207 + /* 208 + * DSS fck gives us very few possibilities, so finding a good pixel 209 + * clock may not be possible. We try multiple times to find the clock, 210 + * each time widening the pixel clock range we look for, up to 211 + * +/- ~15MHz. 212 + */ 213 + 214 + for (i = 0; i < 25; ++i) { 215 + bool ok; 216 + 217 + memset(ctx, 0, sizeof(*ctx)); 218 + if (pck > 1000 * i * i * i) 219 + ctx->pck_min = max(pck - 1000 * i * i * i, 0lu); 220 + else 221 + ctx->pck_min = 0; 222 + ctx->pck_max = pck + 1000 * i * i * i; 223 + 224 + ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx); 225 + if (ok) 226 + return ok; 227 + } 228 + 229 + return false; 230 + } 231 + 232 + 233 + 234 + static int dpi_set_dsi_clk(enum omap_channel channel, 235 + unsigned long pck_req, unsigned long *fck, int *lck_div, 236 + int *pck_div) 237 + { 238 + struct dpi_clk_calc_ctx ctx; 144 239 int r; 240 + bool ok; 145 241 146 - r = dss_calc_clock_div(pck_req, &dss_cinfo, &dispc_cinfo); 242 + ok = dpi_dsi_clk_calc(pck_req, &ctx); 243 + if (!ok) 244 + return -EINVAL; 245 + 246 + r = dsi_pll_set_clock_div(dpi.dsidev, &ctx.dsi_cinfo); 147 247 if (r) 148 248 return r; 149 249 150 - r = dss_set_clock_div(&dss_cinfo); 151 - if (r) 152 - return r; 250 + dss_select_lcd_clk_source(channel, 251 + dpi_get_alt_clk_src(channel)); 153 252 154 - dpi.mgr_config.clock_info = dispc_cinfo; 253 + dpi.mgr_config.clock_info = ctx.dispc_cinfo; 155 254 156 - *fck = dss_cinfo.fck; 157 - *lck_div = dispc_cinfo.lck_div; 158 - *pck_div = dispc_cinfo.pck_div; 255 + *fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 256 + *lck_div = ctx.dispc_cinfo.lck_div; 257 + *pck_div = ctx.dispc_cinfo.pck_div; 159 258 160 259 return 0; 161 260 } 162 261 163 - static int dpi_set_mode(struct omap_dss_device *dssdev) 262 + static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, 263 + int *lck_div, int *pck_div) 264 + { 265 + struct dpi_clk_calc_ctx ctx; 266 + int r; 267 + bool ok; 268 + 269 + ok = dpi_dss_clk_calc(pck_req, &ctx); 270 + if (!ok) 271 + return -EINVAL; 272 + 273 + r = dss_set_clock_div(&ctx.dss_cinfo); 274 + if (r) 275 + return r; 276 + 277 + dpi.mgr_config.clock_info = ctx.dispc_cinfo; 278 + 279 + *fck = ctx.dss_cinfo.fck; 280 + *lck_div = ctx.dispc_cinfo.lck_div; 281 + *pck_div = ctx.dispc_cinfo.pck_div; 282 + 283 + return 0; 284 + } 285 + 286 + static int dpi_set_mode(struct omap_overlay_manager *mgr) 164 287 { 165 288 struct omap_video_timings *t = &dpi.timings; 166 - struct omap_overlay_manager *mgr = dssdev->output->manager; 167 289 int lck_div = 0, pck_div = 0; 168 290 unsigned long fck = 0; 169 291 unsigned long pck; 170 292 int r = 0; 171 293 172 294 if (dpi.dsidev) 173 - r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck, 295 + r = dpi_set_dsi_clk(mgr->id, t->pixel_clock * 1000, &fck, 174 296 &lck_div, &pck_div); 175 297 else 176 - r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck, 298 + r = dpi_set_dispc_clk(t->pixel_clock * 1000, &fck, 177 299 &lck_div, &pck_div); 178 300 if (r) 179 301 return r; ··· 329 179 return 0; 330 180 } 331 181 332 - static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) 182 + static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr) 333 183 { 334 - struct omap_overlay_manager *mgr = dssdev->output->manager; 335 - 336 184 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 337 185 338 186 dpi.mgr_config.stallmode = false; ··· 345 197 346 198 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 347 199 { 348 - struct omap_dss_output *out = dssdev->output; 200 + struct omap_dss_output *out = &dpi.output; 349 201 int r; 350 202 351 203 mutex_lock(&dpi.lock); ··· 378 230 if (r) 379 231 goto err_get_dispc; 380 232 381 - r = dss_dpi_select_source(dssdev->channel); 233 + r = dss_dpi_select_source(out->manager->id); 382 234 if (r) 383 235 goto err_src_sel; 384 236 ··· 392 244 goto err_dsi_pll_init; 393 245 } 394 246 395 - r = dpi_set_mode(dssdev); 247 + r = dpi_set_mode(out->manager); 396 248 if (r) 397 249 goto err_set_mode; 398 250 399 - dpi_config_lcd_manager(dssdev); 251 + dpi_config_lcd_manager(out->manager); 400 252 401 253 mdelay(2); 402 254 ··· 433 285 434 286 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) 435 287 { 436 - struct omap_overlay_manager *mgr = dssdev->output->manager; 288 + struct omap_overlay_manager *mgr = dpi.output.manager; 437 289 438 290 mutex_lock(&dpi.lock); 439 291 ··· 472 324 int dpi_check_timings(struct omap_dss_device *dssdev, 473 325 struct omap_video_timings *timings) 474 326 { 475 - int r; 476 - struct omap_overlay_manager *mgr = dssdev->output->manager; 327 + struct omap_overlay_manager *mgr = dpi.output.manager; 477 328 int lck_div, pck_div; 478 329 unsigned long fck; 479 330 unsigned long pck; 480 - struct dispc_clock_info dispc_cinfo; 331 + struct dpi_clk_calc_ctx ctx; 332 + bool ok; 481 333 482 334 if (mgr && !dispc_mgr_timings_ok(mgr->id, timings)) 483 335 return -EINVAL; ··· 486 338 return -EINVAL; 487 339 488 340 if (dpi.dsidev) { 489 - struct dsi_clock_info dsi_cinfo; 490 - r = dsi_pll_calc_clock_div_pck(dpi.dsidev, 491 - timings->pixel_clock * 1000, 492 - &dsi_cinfo, &dispc_cinfo); 341 + ok = dpi_dsi_clk_calc(timings->pixel_clock * 1000, &ctx); 342 + if (!ok) 343 + return -EINVAL; 493 344 494 - if (r) 495 - return r; 496 - 497 - fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 345 + fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 498 346 } else { 499 - struct dss_clock_info dss_cinfo; 500 - r = dss_calc_clock_div(timings->pixel_clock * 1000, 501 - &dss_cinfo, &dispc_cinfo); 347 + ok = dpi_dss_clk_calc(timings->pixel_clock * 1000, &ctx); 348 + if (!ok) 349 + return -EINVAL; 502 350 503 - if (r) 504 - return r; 505 - 506 - fck = dss_cinfo.fck; 351 + fck = ctx.dss_cinfo.fck; 507 352 } 508 353 509 - lck_div = dispc_cinfo.lck_div; 510 - pck_div = dispc_cinfo.pck_div; 354 + lck_div = ctx.dispc_cinfo.lck_div; 355 + pck_div = ctx.dispc_cinfo.pck_div; 511 356 512 357 pck = fck / lck_div / pck_div / 1000; 513 358 ··· 542 401 return 0; 543 402 } 544 403 404 + /* 405 + * Return a hardcoded channel for the DPI output. This should work for 406 + * current use cases, but this can be later expanded to either resolve 407 + * the channel in some more dynamic manner, or get the channel as a user 408 + * parameter. 409 + */ 410 + static enum omap_channel dpi_get_channel(void) 411 + { 412 + switch (omapdss_get_version()) { 413 + case OMAPDSS_VER_OMAP24xx: 414 + case OMAPDSS_VER_OMAP34xx_ES1: 415 + case OMAPDSS_VER_OMAP34xx_ES3: 416 + case OMAPDSS_VER_OMAP3630: 417 + case OMAPDSS_VER_AM35xx: 418 + return OMAP_DSS_CHANNEL_LCD; 419 + 420 + case OMAPDSS_VER_OMAP4430_ES1: 421 + case OMAPDSS_VER_OMAP4430_ES2: 422 + case OMAPDSS_VER_OMAP4: 423 + return OMAP_DSS_CHANNEL_LCD2; 424 + 425 + case OMAPDSS_VER_OMAP5: 426 + return OMAP_DSS_CHANNEL_LCD3; 427 + 428 + default: 429 + DSSWARN("unsupported DSS version\n"); 430 + return OMAP_DSS_CHANNEL_LCD; 431 + } 432 + } 433 + 545 434 static int __init dpi_init_display(struct omap_dss_device *dssdev) 546 435 { 547 436 struct platform_device *dsidev; ··· 592 421 dpi.vdds_dsi_reg = vdds_dsi; 593 422 } 594 423 595 - /* 596 - * XXX We shouldn't need dssdev->channel for this. The dsi pll clock 597 - * source for DPI is SoC integration detail, not something that should 598 - * be configured in the dssdev 599 - */ 600 - dsidev = dpi_get_dsidev(dssdev->channel); 424 + dsidev = dpi_get_dsidev(dpi.output.dispc_channel); 601 425 602 426 if (dsidev && dpi_verify_dsi_pll(dsidev)) { 603 427 dsidev = NULL; ··· 683 517 out->pdev = pdev; 684 518 out->id = OMAP_DSS_OUTPUT_DPI; 685 519 out->type = OMAP_DISPLAY_TYPE_DPI; 520 + out->name = "dpi.0"; 521 + out->dispc_channel = dpi_get_channel(); 686 522 687 523 dss_register_output(out); 688 524 }
+761 -498
drivers/video/omap2/dss/dsi.c
··· 200 200 201 201 typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); 202 202 203 + static int dsi_display_init_dispc(struct platform_device *dsidev, 204 + struct omap_overlay_manager *mgr); 205 + static void dsi_display_uninit_dispc(struct platform_device *dsidev, 206 + struct omap_overlay_manager *mgr); 207 + 203 208 #define DSI_MAX_NR_ISRS 2 204 209 #define DSI_MAX_NR_LANES 5 205 210 ··· 255 250 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; 256 251 }; 257 252 253 + struct dsi_clk_calc_ctx { 254 + struct platform_device *dsidev; 255 + 256 + /* inputs */ 257 + 258 + const struct omap_dss_dsi_config *config; 259 + 260 + unsigned long req_pck_min, req_pck_nom, req_pck_max; 261 + 262 + /* outputs */ 263 + 264 + struct dsi_clock_info dsi_cinfo; 265 + struct dispc_clock_info dispc_cinfo; 266 + 267 + struct omap_video_timings dispc_vm; 268 + struct omap_dss_dsi_videomode_timings dsi_vm; 269 + }; 270 + 258 271 struct dsi_data { 259 272 struct platform_device *pdev; 260 273 void __iomem *base; ··· 283 260 284 261 struct clk *dss_clk; 285 262 struct clk *sys_clk; 263 + 264 + struct dispc_clock_info user_dispc_cinfo; 265 + struct dsi_clock_info user_dsi_cinfo; 286 266 287 267 struct dsi_clock_info current_cinfo; 288 268 ··· 350 324 unsigned long lpdiv_max; 351 325 352 326 unsigned num_lanes_supported; 327 + unsigned line_buffer_size; 353 328 354 329 struct dsi_lane_config lanes[DSI_MAX_NR_LANES]; 355 330 unsigned num_lanes_used; ··· 1219 1192 return r; 1220 1193 } 1221 1194 1222 - static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) 1195 + static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo, 1196 + unsigned long lp_clk_min, unsigned long lp_clk_max) 1223 1197 { 1224 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 1198 + unsigned long dsi_fclk = cinfo->dsi_pll_hsdiv_dsi_clk; 1199 + unsigned lp_clk_div; 1200 + unsigned long lp_clk; 1201 + 1202 + lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk_max * 2); 1203 + lp_clk = dsi_fclk / 2 / lp_clk_div; 1204 + 1205 + if (lp_clk < lp_clk_min || lp_clk > lp_clk_max) 1206 + return -EINVAL; 1207 + 1208 + cinfo->lp_clk_div = lp_clk_div; 1209 + cinfo->lp_clk = lp_clk; 1210 + 1211 + return 0; 1212 + } 1213 + 1214 + static int dsi_set_lp_clk_divisor(struct platform_device *dsidev) 1215 + { 1225 1216 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1226 1217 unsigned long dsi_fclk; 1227 1218 unsigned lp_clk_div; 1228 1219 unsigned long lp_clk; 1229 1220 1230 - lp_clk_div = dssdev->clocks.dsi.lp_clk_div; 1221 + lp_clk_div = dsi->user_dsi_cinfo.lp_clk_div; 1231 1222 1232 1223 if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max) 1233 1224 return -EINVAL; ··· 1317 1272 return 0; 1318 1273 } 1319 1274 1275 + unsigned long dsi_get_pll_clkin(struct platform_device *dsidev) 1276 + { 1277 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1278 + return clk_get_rate(dsi->sys_clk); 1279 + } 1280 + 1281 + bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll, 1282 + unsigned long out_min, dsi_hsdiv_calc_func func, void *data) 1283 + { 1284 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1285 + int regm, regm_start, regm_stop; 1286 + unsigned long out_max; 1287 + unsigned long out; 1288 + 1289 + out_min = out_min ? out_min : 1; 1290 + out_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1291 + 1292 + regm_start = max(DIV_ROUND_UP(pll, out_max), 1ul); 1293 + regm_stop = min(pll / out_min, dsi->regm_dispc_max); 1294 + 1295 + for (regm = regm_start; regm <= regm_stop; ++regm) { 1296 + out = pll / regm; 1297 + 1298 + if (func(regm, out, data)) 1299 + return true; 1300 + } 1301 + 1302 + return false; 1303 + } 1304 + 1305 + bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin, 1306 + unsigned long pll_min, unsigned long pll_max, 1307 + dsi_pll_calc_func func, void *data) 1308 + { 1309 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1310 + int regn, regn_start, regn_stop; 1311 + int regm, regm_start, regm_stop; 1312 + unsigned long fint, pll; 1313 + const unsigned long pll_hw_max = 1800000000; 1314 + unsigned long fint_hw_min, fint_hw_max; 1315 + 1316 + fint_hw_min = dsi->fint_min; 1317 + fint_hw_max = dsi->fint_max; 1318 + 1319 + regn_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); 1320 + regn_stop = min(clkin / fint_hw_min, dsi->regn_max); 1321 + 1322 + pll_max = pll_max ? pll_max : ULONG_MAX; 1323 + 1324 + for (regn = regn_start; regn <= regn_stop; ++regn) { 1325 + fint = clkin / regn; 1326 + 1327 + regm_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), 1328 + 1ul); 1329 + regm_stop = min3(pll_max / fint / 2, 1330 + pll_hw_max / fint / 2, 1331 + dsi->regm_max); 1332 + 1333 + for (regm = regm_start; regm <= regm_stop; ++regm) { 1334 + pll = 2 * regm * fint; 1335 + 1336 + if (func(regn, regm, fint, pll, data)) 1337 + return true; 1338 + } 1339 + } 1340 + 1341 + return false; 1342 + } 1343 + 1320 1344 /* calculate clock rates using dividers in cinfo */ 1321 1345 static int dsi_calc_clock_rates(struct platform_device *dsidev, 1322 1346 struct dsi_clock_info *cinfo) ··· 1430 1316 return 0; 1431 1317 } 1432 1318 1433 - int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, 1434 - unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, 1435 - struct dispc_clock_info *dispc_cinfo) 1436 - { 1437 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1438 - struct dsi_clock_info cur, best; 1439 - struct dispc_clock_info best_dispc; 1440 - int min_fck_per_pck; 1441 - int match = 0; 1442 - unsigned long dss_sys_clk, max_dss_fck; 1443 - 1444 - dss_sys_clk = clk_get_rate(dsi->sys_clk); 1445 - 1446 - max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1447 - 1448 - if (req_pck == dsi->cache_req_pck && 1449 - dsi->cache_cinfo.clkin == dss_sys_clk) { 1450 - DSSDBG("DSI clock info found from cache\n"); 1451 - *dsi_cinfo = dsi->cache_cinfo; 1452 - dispc_find_clk_divs(req_pck, dsi_cinfo->dsi_pll_hsdiv_dispc_clk, 1453 - dispc_cinfo); 1454 - return 0; 1455 - } 1456 - 1457 - min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1458 - 1459 - if (min_fck_per_pck && 1460 - req_pck * min_fck_per_pck > max_dss_fck) { 1461 - DSSERR("Requested pixel clock not possible with the current " 1462 - "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1463 - "the constraint off.\n"); 1464 - min_fck_per_pck = 0; 1465 - } 1466 - 1467 - DSSDBG("dsi_pll_calc\n"); 1468 - 1469 - retry: 1470 - memset(&best, 0, sizeof(best)); 1471 - memset(&best_dispc, 0, sizeof(best_dispc)); 1472 - 1473 - memset(&cur, 0, sizeof(cur)); 1474 - cur.clkin = dss_sys_clk; 1475 - 1476 - /* 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1477 - /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1478 - for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { 1479 - cur.fint = cur.clkin / cur.regn; 1480 - 1481 - if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) 1482 - continue; 1483 - 1484 - /* DSIPHY(MHz) = (2 * regm / regn) * clkin */ 1485 - for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { 1486 - unsigned long a, b; 1487 - 1488 - a = 2 * cur.regm * (cur.clkin/1000); 1489 - b = cur.regn; 1490 - cur.clkin4ddr = a / b * 1000; 1491 - 1492 - if (cur.clkin4ddr > 1800 * 1000 * 1000) 1493 - break; 1494 - 1495 - /* dsi_pll_hsdiv_dispc_clk(MHz) = 1496 - * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ 1497 - for (cur.regm_dispc = 1; cur.regm_dispc < 1498 - dsi->regm_dispc_max; ++cur.regm_dispc) { 1499 - struct dispc_clock_info cur_dispc; 1500 - cur.dsi_pll_hsdiv_dispc_clk = 1501 - cur.clkin4ddr / cur.regm_dispc; 1502 - 1503 - if (cur.regm_dispc > 1 && 1504 - cur.regm_dispc % 2 != 0 && 1505 - req_pck >= 1000000) 1506 - continue; 1507 - 1508 - /* this will narrow down the search a bit, 1509 - * but still give pixclocks below what was 1510 - * requested */ 1511 - if (cur.dsi_pll_hsdiv_dispc_clk < req_pck) 1512 - break; 1513 - 1514 - if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck) 1515 - continue; 1516 - 1517 - if (min_fck_per_pck && 1518 - cur.dsi_pll_hsdiv_dispc_clk < 1519 - req_pck * min_fck_per_pck) 1520 - continue; 1521 - 1522 - match = 1; 1523 - 1524 - dispc_find_clk_divs(req_pck, 1525 - cur.dsi_pll_hsdiv_dispc_clk, 1526 - &cur_dispc); 1527 - 1528 - if (abs(cur_dispc.pck - req_pck) < 1529 - abs(best_dispc.pck - req_pck)) { 1530 - best = cur; 1531 - best_dispc = cur_dispc; 1532 - 1533 - if (cur_dispc.pck == req_pck) 1534 - goto found; 1535 - } 1536 - } 1537 - } 1538 - } 1539 - found: 1540 - if (!match) { 1541 - if (min_fck_per_pck) { 1542 - DSSERR("Could not find suitable clock settings.\n" 1543 - "Turning FCK/PCK constraint off and" 1544 - "trying again.\n"); 1545 - min_fck_per_pck = 0; 1546 - goto retry; 1547 - } 1548 - 1549 - DSSERR("Could not find suitable clock settings.\n"); 1550 - 1551 - return -EINVAL; 1552 - } 1553 - 1554 - /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */ 1555 - best.regm_dsi = 0; 1556 - best.dsi_pll_hsdiv_dsi_clk = 0; 1557 - 1558 - if (dsi_cinfo) 1559 - *dsi_cinfo = best; 1560 - if (dispc_cinfo) 1561 - *dispc_cinfo = best_dispc; 1562 - 1563 - dsi->cache_req_pck = req_pck; 1564 - dsi->cache_clk_freq = 0; 1565 - dsi->cache_cinfo = best; 1566 - 1567 - return 0; 1568 - } 1569 - 1570 - static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, 1571 - unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo) 1572 - { 1573 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1574 - struct dsi_clock_info cur, best; 1575 - 1576 - DSSDBG("dsi_pll_calc_ddrfreq\n"); 1577 - 1578 - memset(&best, 0, sizeof(best)); 1579 - memset(&cur, 0, sizeof(cur)); 1580 - 1581 - cur.clkin = clk_get_rate(dsi->sys_clk); 1582 - 1583 - for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { 1584 - cur.fint = cur.clkin / cur.regn; 1585 - 1586 - if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) 1587 - continue; 1588 - 1589 - /* DSIPHY(MHz) = (2 * regm / regn) * clkin */ 1590 - for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { 1591 - unsigned long a, b; 1592 - 1593 - a = 2 * cur.regm * (cur.clkin/1000); 1594 - b = cur.regn; 1595 - cur.clkin4ddr = a / b * 1000; 1596 - 1597 - if (cur.clkin4ddr > 1800 * 1000 * 1000) 1598 - break; 1599 - 1600 - if (abs(cur.clkin4ddr - req_clkin4ddr) < 1601 - abs(best.clkin4ddr - req_clkin4ddr)) { 1602 - best = cur; 1603 - DSSDBG("best %ld\n", best.clkin4ddr); 1604 - } 1605 - 1606 - if (cur.clkin4ddr == req_clkin4ddr) 1607 - goto found; 1608 - } 1609 - } 1610 - found: 1611 - if (cinfo) 1612 - *cinfo = best; 1613 - 1614 - return 0; 1615 - } 1616 - 1617 - static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev, 1618 - struct dsi_clock_info *cinfo) 1319 + static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo) 1619 1320 { 1620 1321 unsigned long max_dsi_fck; 1621 1322 ··· 1438 1509 1439 1510 cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); 1440 1511 cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; 1441 - } 1442 - 1443 - static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev, 1444 - unsigned long req_pck, struct dsi_clock_info *cinfo, 1445 - struct dispc_clock_info *dispc_cinfo) 1446 - { 1447 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1448 - unsigned regm_dispc, best_regm_dispc; 1449 - unsigned long dispc_clk, best_dispc_clk; 1450 - int min_fck_per_pck; 1451 - unsigned long max_dss_fck; 1452 - struct dispc_clock_info best_dispc; 1453 - bool match; 1454 - 1455 - max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1456 - 1457 - min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1458 - 1459 - if (min_fck_per_pck && 1460 - req_pck * min_fck_per_pck > max_dss_fck) { 1461 - DSSERR("Requested pixel clock not possible with the current " 1462 - "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1463 - "the constraint off.\n"); 1464 - min_fck_per_pck = 0; 1465 - } 1466 - 1467 - retry: 1468 - best_regm_dispc = 0; 1469 - best_dispc_clk = 0; 1470 - memset(&best_dispc, 0, sizeof(best_dispc)); 1471 - match = false; 1472 - 1473 - for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) { 1474 - struct dispc_clock_info cur_dispc; 1475 - 1476 - dispc_clk = cinfo->clkin4ddr / regm_dispc; 1477 - 1478 - /* this will narrow down the search a bit, 1479 - * but still give pixclocks below what was 1480 - * requested */ 1481 - if (dispc_clk < req_pck) 1482 - break; 1483 - 1484 - if (dispc_clk > max_dss_fck) 1485 - continue; 1486 - 1487 - if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck) 1488 - continue; 1489 - 1490 - match = true; 1491 - 1492 - dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc); 1493 - 1494 - if (abs(cur_dispc.pck - req_pck) < 1495 - abs(best_dispc.pck - req_pck)) { 1496 - best_regm_dispc = regm_dispc; 1497 - best_dispc_clk = dispc_clk; 1498 - best_dispc = cur_dispc; 1499 - 1500 - if (cur_dispc.pck == req_pck) 1501 - goto found; 1502 - } 1503 - } 1504 - 1505 - if (!match) { 1506 - if (min_fck_per_pck) { 1507 - DSSERR("Could not find suitable clock settings.\n" 1508 - "Turning FCK/PCK constraint off and" 1509 - "trying again.\n"); 1510 - min_fck_per_pck = 0; 1511 - goto retry; 1512 - } 1513 - 1514 - DSSERR("Could not find suitable clock settings.\n"); 1515 - 1516 - return -EINVAL; 1517 - } 1518 - found: 1519 - cinfo->regm_dispc = best_regm_dispc; 1520 - cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk; 1521 - 1522 - *dispc_cinfo = best_dispc; 1523 - 1524 - return 0; 1525 1512 } 1526 1513 1527 1514 int dsi_pll_set_clock_div(struct platform_device *dsidev, ··· 2628 2783 2629 2784 static void dsi_vc_initial_config(struct platform_device *dsidev, int channel) 2630 2785 { 2786 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2631 2787 u32 r; 2632 2788 2633 2789 DSSDBG("Initial config of virtual channel %d", channel); ··· 2653 2807 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2654 2808 2655 2809 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r); 2810 + 2811 + dsi->vc[channel].source = DSI_VC_SOURCE_L4; 2656 2812 } 2657 2813 2658 2814 static int dsi_vc_config_source(struct platform_device *dsidev, int channel, ··· 3625 3777 3626 3778 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 3627 3779 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 3628 - unsigned line_buf_size = dsi_get_line_buf_size(dsidev); 3629 3780 struct omap_video_timings *timings = &dsi->timings; 3630 3781 /* 3631 3782 * Don't use line buffers if width is greater than the video 3632 3783 * port's line buffer size 3633 3784 */ 3634 - if (line_buf_size <= timings->x_res * bpp / 8) 3785 + if (dsi->line_buffer_size <= timings->x_res * bpp / 8) 3635 3786 num_line_buffers = 0; 3636 3787 else 3637 3788 num_line_buffers = 2; ··· 3646 3799 static void dsi_config_vp_sync_events(struct platform_device *dsidev) 3647 3800 { 3648 3801 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3649 - bool vsync_end = dsi->vm_timings.vp_vsync_end; 3650 - bool hsync_end = dsi->vm_timings.vp_hsync_end; 3802 + bool sync_end; 3651 3803 u32 r; 3804 + 3805 + if (dsi->vm_timings.trans_mode == OMAP_DSS_DSI_PULSE_MODE) 3806 + sync_end = true; 3807 + else 3808 + sync_end = false; 3652 3809 3653 3810 r = dsi_read_reg(dsidev, DSI_CTRL); 3654 3811 r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */ 3655 3812 r = FLD_MOD(r, 1, 10, 10); /* VP_HSYNC_POL */ 3656 3813 r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */ 3657 3814 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */ 3658 - r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */ 3815 + r = FLD_MOD(r, sync_end, 16, 16); /* VP_VSYNC_END */ 3659 3816 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */ 3660 - r = FLD_MOD(r, hsync_end, 18, 18); /* VP_HSYNC_END */ 3817 + r = FLD_MOD(r, sync_end, 18, 18); /* VP_HSYNC_END */ 3661 3818 dsi_write_reg(dsidev, DSI_CTRL, r); 3662 3819 } 3663 3820 ··· 3748 3897 return max(lp_inter, 0); 3749 3898 } 3750 3899 3751 - static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) 3900 + static void dsi_config_cmd_mode_interleaving(struct platform_device *dsidev) 3752 3901 { 3753 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3754 3902 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3755 3903 int blanking_mode; 3756 3904 int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode; ··· 3760 3910 struct omap_video_timings *timings = &dsi->timings; 3761 3911 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 3762 3912 int ndl = dsi->num_lanes_used - 1; 3763 - int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; 3913 + int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.regm_dsi + 1; 3764 3914 int hsa_interleave_hs = 0, hsa_interleave_lp = 0; 3765 3915 int hfp_interleave_hs = 0, hfp_interleave_lp = 0; 3766 3916 int hbp_interleave_hs = 0, hbp_interleave_lp = 0; ··· 3865 4015 dsi_write_reg(dsidev, DSI_VM_TIMING6, r); 3866 4016 } 3867 4017 3868 - static int dsi_proto_config(struct omap_dss_device *dssdev) 4018 + static int dsi_proto_config(struct platform_device *dsidev) 3869 4019 { 3870 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3871 4020 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3872 4021 u32 r; 3873 4022 int buswidth = 0; ··· 3924 4075 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 3925 4076 dsi_config_vp_sync_events(dsidev); 3926 4077 dsi_config_blanking_modes(dsidev); 3927 - dsi_config_cmd_mode_interleaving(dssdev); 4078 + dsi_config_cmd_mode_interleaving(dsidev); 3928 4079 } 3929 4080 3930 4081 dsi_vc_initial_config(dsidev, 0); ··· 4008 4159 int vfp = dsi->vm_timings.vfp; 4009 4160 int vbp = dsi->vm_timings.vbp; 4010 4161 int window_sync = dsi->vm_timings.window_sync; 4011 - bool hsync_end = dsi->vm_timings.vp_hsync_end; 4162 + bool hsync_end; 4012 4163 struct omap_video_timings *timings = &dsi->timings; 4013 4164 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 4014 4165 int tl, t_he, width_bytes; 4015 4166 4167 + hsync_end = dsi->vm_timings.trans_mode == OMAP_DSS_DSI_PULSE_MODE; 4016 4168 t_he = hsync_end ? 4017 4169 ((hsa == 0 && ndl == 3) ? 1 : DIV_ROUND_UP(4, ndl)) : 0; 4018 4170 ··· 4116 4266 } 4117 4267 EXPORT_SYMBOL(omapdss_dsi_configure_pins); 4118 4268 4119 - int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, 4120 - unsigned long ddr_clk, unsigned long lp_clk) 4121 - { 4122 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4123 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4124 - struct dsi_clock_info cinfo; 4125 - struct dispc_clock_info dispc_cinfo; 4126 - unsigned lp_clk_div; 4127 - unsigned long dsi_fclk; 4128 - int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); 4129 - unsigned long pck; 4130 - int r; 4131 - 4132 - DSSDBG("Setting DSI clocks: ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk); 4133 - 4134 - mutex_lock(&dsi->lock); 4135 - 4136 - /* Calculate PLL output clock */ 4137 - r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo); 4138 - if (r) 4139 - goto err; 4140 - 4141 - /* Calculate PLL's DSI clock */ 4142 - dsi_pll_calc_dsi_fck(dsidev, &cinfo); 4143 - 4144 - /* Calculate PLL's DISPC clock and pck & lck divs */ 4145 - pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; 4146 - DSSDBG("finding dispc dividers for pck %lu\n", pck); 4147 - r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo); 4148 - if (r) 4149 - goto err; 4150 - 4151 - /* Calculate LP clock */ 4152 - dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk; 4153 - lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); 4154 - 4155 - dssdev->clocks.dsi.regn = cinfo.regn; 4156 - dssdev->clocks.dsi.regm = cinfo.regm; 4157 - dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; 4158 - dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; 4159 - 4160 - dssdev->clocks.dsi.lp_clk_div = lp_clk_div; 4161 - 4162 - dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div; 4163 - dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div; 4164 - 4165 - dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK; 4166 - 4167 - dssdev->clocks.dispc.channel.lcd_clk_src = 4168 - dsi->module_id == 0 ? 4169 - OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : 4170 - OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; 4171 - 4172 - dssdev->clocks.dsi.dsi_fclk_src = 4173 - dsi->module_id == 0 ? 4174 - OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : 4175 - OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI; 4176 - 4177 - mutex_unlock(&dsi->lock); 4178 - return 0; 4179 - err: 4180 - mutex_unlock(&dsi->lock); 4181 - return r; 4182 - } 4183 - EXPORT_SYMBOL(omapdss_dsi_set_clocks); 4184 - 4185 4269 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) 4186 4270 { 4187 4271 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4188 4272 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4189 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4273 + struct omap_overlay_manager *mgr = dsi->output.manager; 4190 4274 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 4275 + struct omap_dss_output *out = &dsi->output; 4191 4276 u8 data_type; 4192 4277 u16 word_count; 4193 4278 int r; 4279 + 4280 + if (out == NULL || out->manager == NULL) { 4281 + DSSERR("failed to enable display: no output/manager\n"); 4282 + return -ENODEV; 4283 + } 4284 + 4285 + r = dsi_display_init_dispc(dsidev, mgr); 4286 + if (r) 4287 + goto err_init_dispc; 4194 4288 4195 4289 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4196 4290 switch (dsi->pix_fmt) { ··· 4151 4357 data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; 4152 4358 break; 4153 4359 default: 4154 - BUG(); 4155 - return -EINVAL; 4360 + r = -EINVAL; 4361 + goto err_pix_fmt; 4156 4362 }; 4157 4363 4158 4364 dsi_if_enable(dsidev, false); ··· 4171 4377 } 4172 4378 4173 4379 r = dss_mgr_enable(mgr); 4174 - if (r) { 4175 - if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4176 - dsi_if_enable(dsidev, false); 4177 - dsi_vc_enable(dsidev, channel, false); 4178 - } 4179 - 4180 - return r; 4181 - } 4380 + if (r) 4381 + goto err_mgr_enable; 4182 4382 4183 4383 return 0; 4384 + 4385 + err_mgr_enable: 4386 + if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4387 + dsi_if_enable(dsidev, false); 4388 + dsi_vc_enable(dsidev, channel, false); 4389 + } 4390 + err_pix_fmt: 4391 + dsi_display_uninit_dispc(dsidev, mgr); 4392 + err_init_dispc: 4393 + return r; 4184 4394 } 4185 4395 EXPORT_SYMBOL(dsi_enable_video_output); 4186 4396 ··· 4192 4394 { 4193 4395 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4194 4396 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4195 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4397 + struct omap_overlay_manager *mgr = dsi->output.manager; 4196 4398 4197 4399 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4198 4400 dsi_if_enable(dsidev, false); ··· 4206 4408 } 4207 4409 4208 4410 dss_mgr_disable(mgr); 4411 + 4412 + dsi_display_uninit_dispc(dsidev, mgr); 4209 4413 } 4210 4414 EXPORT_SYMBOL(dsi_disable_video_output); 4211 4415 4212 - static void dsi_update_screen_dispc(struct omap_dss_device *dssdev) 4416 + static void dsi_update_screen_dispc(struct platform_device *dsidev) 4213 4417 { 4214 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4215 4418 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4216 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4419 + struct omap_overlay_manager *mgr = dsi->output.manager; 4217 4420 unsigned bytespp; 4218 4421 unsigned bytespl; 4219 4422 unsigned bytespf; ··· 4224 4425 u32 l; 4225 4426 int r; 4226 4427 const unsigned channel = dsi->update_channel; 4227 - const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); 4428 + const unsigned line_buf_size = dsi->line_buffer_size; 4228 4429 u16 w = dsi->timings.x_res; 4229 4430 u16 h = dsi->timings.y_res; 4230 4431 ··· 4370 4571 dsi->update_bytes = dw * dh * 4371 4572 dsi_get_pixel_size(dsi->pix_fmt) / 8; 4372 4573 #endif 4373 - dsi_update_screen_dispc(dssdev); 4574 + dsi_update_screen_dispc(dsidev); 4374 4575 4375 4576 return 0; 4376 4577 } ··· 4378 4579 4379 4580 /* Display funcs */ 4380 4581 4381 - static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) 4582 + static int dsi_configure_dispc_clocks(struct platform_device *dsidev) 4382 4583 { 4383 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4384 4584 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4385 4585 struct dispc_clock_info dispc_cinfo; 4386 4586 int r; 4387 - unsigned long long fck; 4587 + unsigned long fck; 4388 4588 4389 4589 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev); 4390 4590 4391 - dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div; 4392 - dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div; 4591 + dispc_cinfo.lck_div = dsi->user_dispc_cinfo.lck_div; 4592 + dispc_cinfo.pck_div = dsi->user_dispc_cinfo.pck_div; 4393 4593 4394 4594 r = dispc_calc_clock_rates(fck, &dispc_cinfo); 4395 4595 if (r) { ··· 4401 4603 return 0; 4402 4604 } 4403 4605 4404 - static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4606 + static int dsi_display_init_dispc(struct platform_device *dsidev, 4607 + struct omap_overlay_manager *mgr) 4405 4608 { 4406 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4407 4609 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4408 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4409 4610 int r; 4410 4611 4411 - if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4412 - dsi->timings.hsw = 1; 4413 - dsi->timings.hfp = 1; 4414 - dsi->timings.hbp = 1; 4415 - dsi->timings.vsw = 1; 4416 - dsi->timings.vfp = 0; 4417 - dsi->timings.vbp = 0; 4612 + dss_select_lcd_clk_source(mgr->id, dsi->module_id == 0 ? 4613 + OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : 4614 + OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC); 4418 4615 4616 + if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4419 4617 r = dss_mgr_register_framedone_handler(mgr, 4420 4618 dsi_framedone_irq_callback, dsidev); 4421 4619 if (r) { ··· 4439 4645 4440 4646 dss_mgr_set_timings(mgr, &dsi->timings); 4441 4647 4442 - r = dsi_configure_dispc_clocks(dssdev); 4648 + r = dsi_configure_dispc_clocks(dsidev); 4443 4649 if (r) 4444 4650 goto err1; 4445 4651 ··· 4456 4662 dss_mgr_unregister_framedone_handler(mgr, 4457 4663 dsi_framedone_irq_callback, dsidev); 4458 4664 err: 4665 + dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 4459 4666 return r; 4460 4667 } 4461 4668 4462 - static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4669 + static void dsi_display_uninit_dispc(struct platform_device *dsidev, 4670 + struct omap_overlay_manager *mgr) 4463 4671 { 4464 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4465 4672 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4466 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4467 4673 4468 4674 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) 4469 4675 dss_mgr_unregister_framedone_handler(mgr, 4470 4676 dsi_framedone_irq_callback, dsidev); 4677 + 4678 + dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 4471 4679 } 4472 4680 4473 - static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4681 + static int dsi_configure_dsi_clocks(struct platform_device *dsidev) 4474 4682 { 4475 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4683 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4476 4684 struct dsi_clock_info cinfo; 4477 4685 int r; 4478 4686 4479 - cinfo.regn = dssdev->clocks.dsi.regn; 4480 - cinfo.regm = dssdev->clocks.dsi.regm; 4481 - cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc; 4482 - cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi; 4687 + cinfo = dsi->user_dsi_cinfo; 4688 + 4483 4689 r = dsi_calc_clock_rates(dsidev, &cinfo); 4484 4690 if (r) { 4485 4691 DSSERR("Failed to calc dsi clocks\n"); ··· 4495 4701 return 0; 4496 4702 } 4497 4703 4498 - static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4704 + static int dsi_display_init_dsi(struct platform_device *dsidev) 4499 4705 { 4500 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4501 4706 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4502 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4503 4707 int r; 4504 4708 4505 4709 r = dsi_pll_init(dsidev, true, true); 4506 4710 if (r) 4507 4711 goto err0; 4508 4712 4509 - r = dsi_configure_dsi_clocks(dssdev); 4713 + r = dsi_configure_dsi_clocks(dsidev); 4510 4714 if (r) 4511 4715 goto err1; 4512 4716 4513 - dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); 4514 - dss_select_lcd_clk_source(mgr->id, 4515 - dssdev->clocks.dispc.channel.lcd_clk_src); 4717 + dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ? 4718 + OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : 4719 + OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI); 4516 4720 4517 4721 DSSDBG("PLL OK\n"); 4518 4722 ··· 4521 4729 _dsi_print_reset_status(dsidev); 4522 4730 4523 4731 dsi_proto_timings(dsidev); 4524 - dsi_set_lp_clk_divisor(dssdev); 4732 + dsi_set_lp_clk_divisor(dsidev); 4525 4733 4526 4734 if (1) 4527 4735 _dsi_print_reset_status(dsidev); 4528 4736 4529 - r = dsi_proto_config(dssdev); 4737 + r = dsi_proto_config(dsidev); 4530 4738 if (r) 4531 4739 goto err3; 4532 4740 ··· 4543 4751 dsi_cio_uninit(dsidev); 4544 4752 err2: 4545 4753 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4546 - dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 4547 - 4548 4754 err1: 4549 4755 dsi_pll_uninit(dsidev, true); 4550 4756 err0: 4551 4757 return r; 4552 4758 } 4553 4759 4554 - static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, 4760 + static void dsi_display_uninit_dsi(struct platform_device *dsidev, 4555 4761 bool disconnect_lanes, bool enter_ulps) 4556 4762 { 4557 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4558 4763 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4559 - struct omap_overlay_manager *mgr = dssdev->output->manager; 4560 4764 4561 4765 if (enter_ulps && !dsi->ulps_enabled) 4562 4766 dsi_enter_ulps(dsidev); ··· 4565 4777 dsi_vc_enable(dsidev, 3, 0); 4566 4778 4567 4779 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4568 - dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 4569 4780 dsi_cio_uninit(dsidev); 4570 4781 dsi_pll_uninit(dsidev, disconnect_lanes); 4571 4782 } ··· 4573 4786 { 4574 4787 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4575 4788 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4576 - struct omap_dss_output *out = dssdev->output; 4577 4789 int r = 0; 4578 4790 4579 4791 DSSDBG("dsi_display_enable\n"); ··· 4580 4794 WARN_ON(!dsi_bus_is_locked(dsidev)); 4581 4795 4582 4796 mutex_lock(&dsi->lock); 4583 - 4584 - if (out == NULL || out->manager == NULL) { 4585 - DSSERR("failed to enable display: no output/manager\n"); 4586 - r = -ENODEV; 4587 - goto err_start_dev; 4588 - } 4589 4797 4590 4798 r = omap_dss_start_device(dssdev); 4591 4799 if (r) { ··· 4595 4815 4596 4816 _dsi_initialize_irq(dsidev); 4597 4817 4598 - r = dsi_display_init_dispc(dssdev); 4599 - if (r) 4600 - goto err_init_dispc; 4601 - 4602 - r = dsi_display_init_dsi(dssdev); 4818 + r = dsi_display_init_dsi(dsidev); 4603 4819 if (r) 4604 4820 goto err_init_dsi; 4605 4821 ··· 4604 4828 return 0; 4605 4829 4606 4830 err_init_dsi: 4607 - dsi_display_uninit_dispc(dssdev); 4608 - err_init_dispc: 4609 4831 dsi_enable_pll_clock(dsidev, 0); 4610 4832 dsi_runtime_put(dsidev); 4611 4833 err_get_dsi: ··· 4632 4858 dsi_sync_vc(dsidev, 2); 4633 4859 dsi_sync_vc(dsidev, 3); 4634 4860 4635 - dsi_display_uninit_dispc(dssdev); 4636 - 4637 - dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps); 4861 + dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps); 4638 4862 4639 4863 dsi_runtime_put(dsidev); 4640 4864 dsi_enable_pll_clock(dsidev, 0); ··· 4653 4881 } 4654 4882 EXPORT_SYMBOL(omapdss_dsi_enable_te); 4655 4883 4656 - void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, 4657 - struct omap_video_timings *timings) 4884 + #ifdef PRINT_VERBOSE_VM_TIMINGS 4885 + static void print_dsi_vm(const char *str, 4886 + const struct omap_dss_dsi_videomode_timings *t) 4887 + { 4888 + unsigned long byteclk = t->hsclk / 4; 4889 + int bl, wc, pps, tot; 4890 + 4891 + wc = DIV_ROUND_UP(t->hact * t->bitspp, 8); 4892 + pps = DIV_ROUND_UP(wc + 6, t->ndl); /* pixel packet size */ 4893 + bl = t->hss + t->hsa + t->hse + t->hbp + t->hfp; 4894 + tot = bl + pps; 4895 + 4896 + #define TO_DSI_T(x) ((u32)div64_u64((u64)x * 1000000000llu, byteclk)) 4897 + 4898 + pr_debug("%s bck %lu, %u/%u/%u/%u/%u/%u = %u+%u = %u, " 4899 + "%u/%u/%u/%u/%u/%u = %u + %u = %u\n", 4900 + str, 4901 + byteclk, 4902 + t->hss, t->hsa, t->hse, t->hbp, pps, t->hfp, 4903 + bl, pps, tot, 4904 + TO_DSI_T(t->hss), 4905 + TO_DSI_T(t->hsa), 4906 + TO_DSI_T(t->hse), 4907 + TO_DSI_T(t->hbp), 4908 + TO_DSI_T(pps), 4909 + TO_DSI_T(t->hfp), 4910 + 4911 + TO_DSI_T(bl), 4912 + TO_DSI_T(pps), 4913 + 4914 + TO_DSI_T(tot)); 4915 + #undef TO_DSI_T 4916 + } 4917 + 4918 + static void print_dispc_vm(const char *str, const struct omap_video_timings *t) 4919 + { 4920 + unsigned long pck = t->pixel_clock * 1000; 4921 + int hact, bl, tot; 4922 + 4923 + hact = t->x_res; 4924 + bl = t->hsw + t->hbp + t->hfp; 4925 + tot = hact + bl; 4926 + 4927 + #define TO_DISPC_T(x) ((u32)div64_u64((u64)x * 1000000000llu, pck)) 4928 + 4929 + pr_debug("%s pck %lu, %u/%u/%u/%u = %u+%u = %u, " 4930 + "%u/%u/%u/%u = %u + %u = %u\n", 4931 + str, 4932 + pck, 4933 + t->hsw, t->hbp, hact, t->hfp, 4934 + bl, hact, tot, 4935 + TO_DISPC_T(t->hsw), 4936 + TO_DISPC_T(t->hbp), 4937 + TO_DISPC_T(hact), 4938 + TO_DISPC_T(t->hfp), 4939 + TO_DISPC_T(bl), 4940 + TO_DISPC_T(hact), 4941 + TO_DISPC_T(tot)); 4942 + #undef TO_DISPC_T 4943 + } 4944 + 4945 + /* note: this is not quite accurate */ 4946 + static void print_dsi_dispc_vm(const char *str, 4947 + const struct omap_dss_dsi_videomode_timings *t) 4948 + { 4949 + struct omap_video_timings vm = { 0 }; 4950 + unsigned long byteclk = t->hsclk / 4; 4951 + unsigned long pck; 4952 + u64 dsi_tput; 4953 + int dsi_hact, dsi_htot; 4954 + 4955 + dsi_tput = (u64)byteclk * t->ndl * 8; 4956 + pck = (u32)div64_u64(dsi_tput, t->bitspp); 4957 + dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(t->hact * t->bitspp, 8) + 6, t->ndl); 4958 + dsi_htot = t->hss + t->hsa + t->hse + t->hbp + dsi_hact + t->hfp; 4959 + 4960 + vm.pixel_clock = pck / 1000; 4961 + vm.hsw = div64_u64((u64)(t->hsa + t->hse) * pck, byteclk); 4962 + vm.hbp = div64_u64((u64)t->hbp * pck, byteclk); 4963 + vm.hfp = div64_u64((u64)t->hfp * pck, byteclk); 4964 + vm.x_res = t->hact; 4965 + 4966 + print_dispc_vm(str, &vm); 4967 + } 4968 + #endif /* PRINT_VERBOSE_VM_TIMINGS */ 4969 + 4970 + static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck, 4971 + unsigned long pck, void *data) 4972 + { 4973 + struct dsi_clk_calc_ctx *ctx = data; 4974 + struct omap_video_timings *t = &ctx->dispc_vm; 4975 + 4976 + ctx->dispc_cinfo.lck_div = lckd; 4977 + ctx->dispc_cinfo.pck_div = pckd; 4978 + ctx->dispc_cinfo.lck = lck; 4979 + ctx->dispc_cinfo.pck = pck; 4980 + 4981 + *t = *ctx->config->timings; 4982 + t->pixel_clock = pck / 1000; 4983 + t->x_res = ctx->config->timings->x_res; 4984 + t->y_res = ctx->config->timings->y_res; 4985 + t->hsw = t->hfp = t->hbp = t->vsw = 1; 4986 + t->vfp = t->vbp = 0; 4987 + 4988 + return true; 4989 + } 4990 + 4991 + static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, 4992 + void *data) 4993 + { 4994 + struct dsi_clk_calc_ctx *ctx = data; 4995 + 4996 + ctx->dsi_cinfo.regm_dispc = regm_dispc; 4997 + ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; 4998 + 4999 + return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max, 5000 + dsi_cm_calc_dispc_cb, ctx); 5001 + } 5002 + 5003 + static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint, 5004 + unsigned long pll, void *data) 5005 + { 5006 + struct dsi_clk_calc_ctx *ctx = data; 5007 + 5008 + ctx->dsi_cinfo.regn = regn; 5009 + ctx->dsi_cinfo.regm = regm; 5010 + ctx->dsi_cinfo.fint = fint; 5011 + ctx->dsi_cinfo.clkin4ddr = pll; 5012 + 5013 + return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, 5014 + dsi_cm_calc_hsdiv_cb, ctx); 5015 + } 5016 + 5017 + static bool dsi_cm_calc(struct dsi_data *dsi, 5018 + const struct omap_dss_dsi_config *cfg, 5019 + struct dsi_clk_calc_ctx *ctx) 5020 + { 5021 + unsigned long clkin; 5022 + int bitspp, ndl; 5023 + unsigned long pll_min, pll_max; 5024 + unsigned long pck, txbyteclk; 5025 + 5026 + clkin = clk_get_rate(dsi->sys_clk); 5027 + bitspp = dsi_get_pixel_size(cfg->pixel_format); 5028 + ndl = dsi->num_lanes_used - 1; 5029 + 5030 + /* 5031 + * Here we should calculate minimum txbyteclk to be able to send the 5032 + * frame in time, and also to handle TE. That's not very simple, though, 5033 + * especially as we go to LP between each pixel packet due to HW 5034 + * "feature". So let's just estimate very roughly and multiply by 1.5. 5035 + */ 5036 + pck = cfg->timings->pixel_clock * 1000; 5037 + pck = pck * 3 / 2; 5038 + txbyteclk = pck * bitspp / 8 / ndl; 5039 + 5040 + memset(ctx, 0, sizeof(*ctx)); 5041 + ctx->dsidev = dsi->pdev; 5042 + ctx->config = cfg; 5043 + ctx->req_pck_min = pck; 5044 + ctx->req_pck_nom = pck; 5045 + ctx->req_pck_max = pck * 3 / 2; 5046 + ctx->dsi_cinfo.clkin = clkin; 5047 + 5048 + pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); 5049 + pll_max = cfg->hs_clk_max * 4; 5050 + 5051 + return dsi_pll_calc(dsi->pdev, clkin, 5052 + pll_min, pll_max, 5053 + dsi_cm_calc_pll_cb, ctx); 5054 + } 5055 + 5056 + static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx) 5057 + { 5058 + struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev); 5059 + const struct omap_dss_dsi_config *cfg = ctx->config; 5060 + int bitspp = dsi_get_pixel_size(cfg->pixel_format); 5061 + int ndl = dsi->num_lanes_used - 1; 5062 + unsigned long hsclk = ctx->dsi_cinfo.clkin4ddr / 4; 5063 + unsigned long byteclk = hsclk / 4; 5064 + 5065 + unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max; 5066 + int xres; 5067 + int panel_htot, panel_hbl; /* pixels */ 5068 + int dispc_htot, dispc_hbl; /* pixels */ 5069 + int dsi_htot, dsi_hact, dsi_hbl, hss, hse; /* byteclks */ 5070 + int hfp, hsa, hbp; 5071 + const struct omap_video_timings *req_vm; 5072 + struct omap_video_timings *dispc_vm; 5073 + struct omap_dss_dsi_videomode_timings *dsi_vm; 5074 + u64 dsi_tput, dispc_tput; 5075 + 5076 + dsi_tput = (u64)byteclk * ndl * 8; 5077 + 5078 + req_vm = cfg->timings; 5079 + req_pck_min = ctx->req_pck_min; 5080 + req_pck_max = ctx->req_pck_max; 5081 + req_pck_nom = ctx->req_pck_nom; 5082 + 5083 + dispc_pck = ctx->dispc_cinfo.pck; 5084 + dispc_tput = (u64)dispc_pck * bitspp; 5085 + 5086 + xres = req_vm->x_res; 5087 + 5088 + panel_hbl = req_vm->hfp + req_vm->hbp + req_vm->hsw; 5089 + panel_htot = xres + panel_hbl; 5090 + 5091 + dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(xres * bitspp, 8) + 6, ndl); 5092 + 5093 + /* 5094 + * When there are no line buffers, DISPC and DSI must have the 5095 + * same tput. Otherwise DISPC tput needs to be higher than DSI's. 5096 + */ 5097 + if (dsi->line_buffer_size < xres * bitspp / 8) { 5098 + if (dispc_tput != dsi_tput) 5099 + return false; 5100 + } else { 5101 + if (dispc_tput < dsi_tput) 5102 + return false; 5103 + } 5104 + 5105 + /* DSI tput must be over the min requirement */ 5106 + if (dsi_tput < (u64)bitspp * req_pck_min) 5107 + return false; 5108 + 5109 + /* When non-burst mode, DSI tput must be below max requirement. */ 5110 + if (cfg->trans_mode != OMAP_DSS_DSI_BURST_MODE) { 5111 + if (dsi_tput > (u64)bitspp * req_pck_max) 5112 + return false; 5113 + } 5114 + 5115 + hss = DIV_ROUND_UP(4, ndl); 5116 + 5117 + if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) { 5118 + if (ndl == 3 && req_vm->hsw == 0) 5119 + hse = 1; 5120 + else 5121 + hse = DIV_ROUND_UP(4, ndl); 5122 + } else { 5123 + hse = 0; 5124 + } 5125 + 5126 + /* DSI htot to match the panel's nominal pck */ 5127 + dsi_htot = div64_u64((u64)panel_htot * byteclk, req_pck_nom); 5128 + 5129 + /* fail if there would be no time for blanking */ 5130 + if (dsi_htot < hss + hse + dsi_hact) 5131 + return false; 5132 + 5133 + /* total DSI blanking needed to achieve panel's TL */ 5134 + dsi_hbl = dsi_htot - dsi_hact; 5135 + 5136 + /* DISPC htot to match the DSI TL */ 5137 + dispc_htot = div64_u64((u64)dsi_htot * dispc_pck, byteclk); 5138 + 5139 + /* verify that the DSI and DISPC TLs are the same */ 5140 + if ((u64)dsi_htot * dispc_pck != (u64)dispc_htot * byteclk) 5141 + return false; 5142 + 5143 + dispc_hbl = dispc_htot - xres; 5144 + 5145 + /* setup DSI videomode */ 5146 + 5147 + dsi_vm = &ctx->dsi_vm; 5148 + memset(dsi_vm, 0, sizeof(*dsi_vm)); 5149 + 5150 + dsi_vm->hsclk = hsclk; 5151 + 5152 + dsi_vm->ndl = ndl; 5153 + dsi_vm->bitspp = bitspp; 5154 + 5155 + if (cfg->trans_mode != OMAP_DSS_DSI_PULSE_MODE) { 5156 + hsa = 0; 5157 + } else if (ndl == 3 && req_vm->hsw == 0) { 5158 + hsa = 0; 5159 + } else { 5160 + hsa = div64_u64((u64)req_vm->hsw * byteclk, req_pck_nom); 5161 + hsa = max(hsa - hse, 1); 5162 + } 5163 + 5164 + hbp = div64_u64((u64)req_vm->hbp * byteclk, req_pck_nom); 5165 + hbp = max(hbp, 1); 5166 + 5167 + hfp = dsi_hbl - (hss + hsa + hse + hbp); 5168 + if (hfp < 1) { 5169 + int t; 5170 + /* we need to take cycles from hbp */ 5171 + 5172 + t = 1 - hfp; 5173 + hbp = max(hbp - t, 1); 5174 + hfp = dsi_hbl - (hss + hsa + hse + hbp); 5175 + 5176 + if (hfp < 1 && hsa > 0) { 5177 + /* we need to take cycles from hsa */ 5178 + t = 1 - hfp; 5179 + hsa = max(hsa - t, 1); 5180 + hfp = dsi_hbl - (hss + hsa + hse + hbp); 5181 + } 5182 + } 5183 + 5184 + if (hfp < 1) 5185 + return false; 5186 + 5187 + dsi_vm->hss = hss; 5188 + dsi_vm->hsa = hsa; 5189 + dsi_vm->hse = hse; 5190 + dsi_vm->hbp = hbp; 5191 + dsi_vm->hact = xres; 5192 + dsi_vm->hfp = hfp; 5193 + 5194 + dsi_vm->vsa = req_vm->vsw; 5195 + dsi_vm->vbp = req_vm->vbp; 5196 + dsi_vm->vact = req_vm->y_res; 5197 + dsi_vm->vfp = req_vm->vfp; 5198 + 5199 + dsi_vm->trans_mode = cfg->trans_mode; 5200 + 5201 + dsi_vm->blanking_mode = 0; 5202 + dsi_vm->hsa_blanking_mode = 1; 5203 + dsi_vm->hfp_blanking_mode = 1; 5204 + dsi_vm->hbp_blanking_mode = 1; 5205 + 5206 + dsi_vm->ddr_clk_always_on = cfg->ddr_clk_always_on; 5207 + dsi_vm->window_sync = 4; 5208 + 5209 + /* setup DISPC videomode */ 5210 + 5211 + dispc_vm = &ctx->dispc_vm; 5212 + *dispc_vm = *req_vm; 5213 + dispc_vm->pixel_clock = dispc_pck / 1000; 5214 + 5215 + if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) { 5216 + hsa = div64_u64((u64)req_vm->hsw * dispc_pck, 5217 + req_pck_nom); 5218 + hsa = max(hsa, 1); 5219 + } else { 5220 + hsa = 1; 5221 + } 5222 + 5223 + hbp = div64_u64((u64)req_vm->hbp * dispc_pck, req_pck_nom); 5224 + hbp = max(hbp, 1); 5225 + 5226 + hfp = dispc_hbl - hsa - hbp; 5227 + if (hfp < 1) { 5228 + int t; 5229 + /* we need to take cycles from hbp */ 5230 + 5231 + t = 1 - hfp; 5232 + hbp = max(hbp - t, 1); 5233 + hfp = dispc_hbl - hsa - hbp; 5234 + 5235 + if (hfp < 1) { 5236 + /* we need to take cycles from hsa */ 5237 + t = 1 - hfp; 5238 + hsa = max(hsa - t, 1); 5239 + hfp = dispc_hbl - hsa - hbp; 5240 + } 5241 + } 5242 + 5243 + if (hfp < 1) 5244 + return false; 5245 + 5246 + dispc_vm->hfp = hfp; 5247 + dispc_vm->hsw = hsa; 5248 + dispc_vm->hbp = hbp; 5249 + 5250 + return true; 5251 + } 5252 + 5253 + 5254 + static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck, 5255 + unsigned long pck, void *data) 5256 + { 5257 + struct dsi_clk_calc_ctx *ctx = data; 5258 + 5259 + ctx->dispc_cinfo.lck_div = lckd; 5260 + ctx->dispc_cinfo.pck_div = pckd; 5261 + ctx->dispc_cinfo.lck = lck; 5262 + ctx->dispc_cinfo.pck = pck; 5263 + 5264 + if (dsi_vm_calc_blanking(ctx) == false) 5265 + return false; 5266 + 5267 + #ifdef PRINT_VERBOSE_VM_TIMINGS 5268 + print_dispc_vm("dispc", &ctx->dispc_vm); 5269 + print_dsi_vm("dsi ", &ctx->dsi_vm); 5270 + print_dispc_vm("req ", ctx->config->timings); 5271 + print_dsi_dispc_vm("act ", &ctx->dsi_vm); 5272 + #endif 5273 + 5274 + return true; 5275 + } 5276 + 5277 + static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, 5278 + void *data) 5279 + { 5280 + struct dsi_clk_calc_ctx *ctx = data; 5281 + unsigned long pck_max; 5282 + 5283 + ctx->dsi_cinfo.regm_dispc = regm_dispc; 5284 + ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; 5285 + 5286 + /* 5287 + * In burst mode we can let the dispc pck be arbitrarily high, but it 5288 + * limits our scaling abilities. So for now, don't aim too high. 5289 + */ 5290 + 5291 + if (ctx->config->trans_mode == OMAP_DSS_DSI_BURST_MODE) 5292 + pck_max = ctx->req_pck_max + 10000000; 5293 + else 5294 + pck_max = ctx->req_pck_max; 5295 + 5296 + return dispc_div_calc(dispc, ctx->req_pck_min, pck_max, 5297 + dsi_vm_calc_dispc_cb, ctx); 5298 + } 5299 + 5300 + static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint, 5301 + unsigned long pll, void *data) 5302 + { 5303 + struct dsi_clk_calc_ctx *ctx = data; 5304 + 5305 + ctx->dsi_cinfo.regn = regn; 5306 + ctx->dsi_cinfo.regm = regm; 5307 + ctx->dsi_cinfo.fint = fint; 5308 + ctx->dsi_cinfo.clkin4ddr = pll; 5309 + 5310 + return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, 5311 + dsi_vm_calc_hsdiv_cb, ctx); 5312 + } 5313 + 5314 + static bool dsi_vm_calc(struct dsi_data *dsi, 5315 + const struct omap_dss_dsi_config *cfg, 5316 + struct dsi_clk_calc_ctx *ctx) 5317 + { 5318 + const struct omap_video_timings *t = cfg->timings; 5319 + unsigned long clkin; 5320 + unsigned long pll_min; 5321 + unsigned long pll_max; 5322 + int ndl = dsi->num_lanes_used - 1; 5323 + int bitspp = dsi_get_pixel_size(cfg->pixel_format); 5324 + unsigned long byteclk_min; 5325 + 5326 + clkin = clk_get_rate(dsi->sys_clk); 5327 + 5328 + memset(ctx, 0, sizeof(*ctx)); 5329 + ctx->dsidev = dsi->pdev; 5330 + ctx->config = cfg; 5331 + 5332 + ctx->dsi_cinfo.clkin = clkin; 5333 + 5334 + /* these limits should come from the panel driver */ 5335 + ctx->req_pck_min = t->pixel_clock * 1000 - 1000; 5336 + ctx->req_pck_nom = t->pixel_clock * 1000; 5337 + ctx->req_pck_max = t->pixel_clock * 1000 + 1000; 5338 + 5339 + byteclk_min = div64_u64((u64)ctx->req_pck_min * bitspp, ndl * 8); 5340 + pll_min = max(cfg->hs_clk_min * 4, byteclk_min * 4 * 4); 5341 + 5342 + if (cfg->trans_mode == OMAP_DSS_DSI_BURST_MODE) { 5343 + pll_max = cfg->hs_clk_max * 4; 5344 + } else { 5345 + unsigned long byteclk_max; 5346 + byteclk_max = div64_u64((u64)ctx->req_pck_max * bitspp, 5347 + ndl * 8); 5348 + 5349 + pll_max = byteclk_max * 4 * 4; 5350 + } 5351 + 5352 + return dsi_pll_calc(dsi->pdev, clkin, 5353 + pll_min, pll_max, 5354 + dsi_vm_calc_pll_cb, ctx); 5355 + } 5356 + 5357 + int omapdss_dsi_set_config(struct omap_dss_device *dssdev, 5358 + const struct omap_dss_dsi_config *config) 4658 5359 { 4659 5360 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4660 5361 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5362 + struct dsi_clk_calc_ctx ctx; 5363 + bool ok; 5364 + int r; 4661 5365 4662 5366 mutex_lock(&dsi->lock); 4663 5367 4664 - dsi->timings = *timings; 5368 + dsi->pix_fmt = config->pixel_format; 5369 + dsi->mode = config->mode; 5370 + 5371 + if (config->mode == OMAP_DSS_DSI_VIDEO_MODE) 5372 + ok = dsi_vm_calc(dsi, config, &ctx); 5373 + else 5374 + ok = dsi_cm_calc(dsi, config, &ctx); 5375 + 5376 + if (!ok) { 5377 + DSSERR("failed to find suitable DSI clock settings\n"); 5378 + r = -EINVAL; 5379 + goto err; 5380 + } 5381 + 5382 + dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo); 5383 + 5384 + r = dsi_lp_clock_calc(&ctx.dsi_cinfo, config->lp_clk_min, 5385 + config->lp_clk_max); 5386 + if (r) { 5387 + DSSERR("failed to find suitable DSI LP clock settings\n"); 5388 + goto err; 5389 + } 5390 + 5391 + dsi->user_dsi_cinfo = ctx.dsi_cinfo; 5392 + dsi->user_dispc_cinfo = ctx.dispc_cinfo; 5393 + 5394 + dsi->timings = ctx.dispc_vm; 5395 + dsi->vm_timings = ctx.dsi_vm; 4665 5396 4666 5397 mutex_unlock(&dsi->lock); 4667 - } 4668 - EXPORT_SYMBOL(omapdss_dsi_set_timings); 4669 5398 4670 - void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) 5399 + return 0; 5400 + err: 5401 + mutex_unlock(&dsi->lock); 5402 + 5403 + return r; 5404 + } 5405 + EXPORT_SYMBOL(omapdss_dsi_set_config); 5406 + 5407 + /* 5408 + * Return a hardcoded channel for the DSI output. This should work for 5409 + * current use cases, but this can be later expanded to either resolve 5410 + * the channel in some more dynamic manner, or get the channel as a user 5411 + * parameter. 5412 + */ 5413 + static enum omap_channel dsi_get_channel(int module_id) 4671 5414 { 4672 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4673 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5415 + switch (omapdss_get_version()) { 5416 + case OMAPDSS_VER_OMAP24xx: 5417 + DSSWARN("DSI not supported\n"); 5418 + return OMAP_DSS_CHANNEL_LCD; 4674 5419 4675 - mutex_lock(&dsi->lock); 5420 + case OMAPDSS_VER_OMAP34xx_ES1: 5421 + case OMAPDSS_VER_OMAP34xx_ES3: 5422 + case OMAPDSS_VER_OMAP3630: 5423 + case OMAPDSS_VER_AM35xx: 5424 + return OMAP_DSS_CHANNEL_LCD; 4676 5425 4677 - dsi->timings.x_res = w; 4678 - dsi->timings.y_res = h; 5426 + case OMAPDSS_VER_OMAP4430_ES1: 5427 + case OMAPDSS_VER_OMAP4430_ES2: 5428 + case OMAPDSS_VER_OMAP4: 5429 + switch (module_id) { 5430 + case 0: 5431 + return OMAP_DSS_CHANNEL_LCD; 5432 + case 1: 5433 + return OMAP_DSS_CHANNEL_LCD2; 5434 + default: 5435 + DSSWARN("unsupported module id\n"); 5436 + return OMAP_DSS_CHANNEL_LCD; 5437 + } 4679 5438 4680 - mutex_unlock(&dsi->lock); 5439 + case OMAPDSS_VER_OMAP5: 5440 + switch (module_id) { 5441 + case 0: 5442 + return OMAP_DSS_CHANNEL_LCD; 5443 + case 1: 5444 + return OMAP_DSS_CHANNEL_LCD3; 5445 + default: 5446 + DSSWARN("unsupported module id\n"); 5447 + return OMAP_DSS_CHANNEL_LCD; 5448 + } 5449 + 5450 + default: 5451 + DSSWARN("unsupported DSS version\n"); 5452 + return OMAP_DSS_CHANNEL_LCD; 5453 + } 4681 5454 } 4682 - EXPORT_SYMBOL(omapdss_dsi_set_size); 4683 - 4684 - void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, 4685 - enum omap_dss_dsi_pixel_format fmt) 4686 - { 4687 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4688 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4689 - 4690 - mutex_lock(&dsi->lock); 4691 - 4692 - dsi->pix_fmt = fmt; 4693 - 4694 - mutex_unlock(&dsi->lock); 4695 - } 4696 - EXPORT_SYMBOL(omapdss_dsi_set_pixel_format); 4697 - 4698 - void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, 4699 - enum omap_dss_dsi_mode mode) 4700 - { 4701 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4702 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4703 - 4704 - mutex_lock(&dsi->lock); 4705 - 4706 - dsi->mode = mode; 4707 - 4708 - mutex_unlock(&dsi->lock); 4709 - } 4710 - EXPORT_SYMBOL(omapdss_dsi_set_operation_mode); 4711 - 4712 - void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, 4713 - struct omap_dss_dsi_videomode_timings *timings) 4714 - { 4715 - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4716 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4717 - 4718 - mutex_lock(&dsi->lock); 4719 - 4720 - dsi->vm_timings = *timings; 4721 - 4722 - mutex_unlock(&dsi->lock); 4723 - } 4724 - EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings); 4725 5455 4726 5456 static int __init dsi_init_display(struct omap_dss_device *dssdev) 4727 5457 { ··· 5347 5073 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5348 5074 struct clk *clk; 5349 5075 5350 - clk = clk_get(&dsidev->dev, "fck"); 5076 + clk = devm_clk_get(&dsidev->dev, "fck"); 5351 5077 if (IS_ERR(clk)) { 5352 5078 DSSERR("can't get fck\n"); 5353 5079 return PTR_ERR(clk); ··· 5355 5081 5356 5082 dsi->dss_clk = clk; 5357 5083 5358 - clk = clk_get(&dsidev->dev, "sys_clk"); 5084 + clk = devm_clk_get(&dsidev->dev, "sys_clk"); 5359 5085 if (IS_ERR(clk)) { 5360 5086 DSSERR("can't get sys_clk\n"); 5361 - clk_put(dsi->dss_clk); 5362 - dsi->dss_clk = NULL; 5363 5087 return PTR_ERR(clk); 5364 5088 } 5365 5089 5366 5090 dsi->sys_clk = clk; 5367 5091 5368 5092 return 0; 5369 - } 5370 - 5371 - static void dsi_put_clocks(struct platform_device *dsidev) 5372 - { 5373 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5374 - 5375 - if (dsi->dss_clk) 5376 - clk_put(dsi->dss_clk); 5377 - if (dsi->sys_clk) 5378 - clk_put(dsi->sys_clk); 5379 5093 } 5380 5094 5381 5095 static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev) ··· 5450 5188 OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; 5451 5189 5452 5190 out->type = OMAP_DISPLAY_TYPE_DSI; 5191 + out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1"; 5192 + out->dispc_channel = dsi_get_channel(dsi->module_id); 5453 5193 5454 5194 dss_register_output(out); 5455 5195 } ··· 5557 5293 else 5558 5294 dsi->num_lanes_supported = 3; 5559 5295 5296 + dsi->line_buffer_size = dsi_get_line_buf_size(dsidev); 5297 + 5560 5298 dsi_init_output(dsidev); 5561 5299 5562 5300 dsi_probe_pdata(dsidev); ··· 5580 5314 5581 5315 err_runtime_get: 5582 5316 pm_runtime_disable(&dsidev->dev); 5583 - dsi_put_clocks(dsidev); 5584 5317 return r; 5585 5318 } 5586 5319 ··· 5594 5329 dsi_uninit_output(dsidev); 5595 5330 5596 5331 pm_runtime_disable(&dsidev->dev); 5597 - 5598 - dsi_put_clocks(dsidev); 5599 5332 5600 5333 if (dsi->vdds_dsi_reg != NULL) { 5601 5334 if (dsi->vdds_dsi_enabled) {
+49 -132
drivers/video/omap2/dss/dss.c
··· 473 473 return 0; 474 474 } 475 475 476 + bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) 477 + { 478 + int fckd, fckd_start, fckd_stop; 479 + unsigned long fck; 480 + unsigned long fck_hw_max; 481 + unsigned long fckd_hw_max; 482 + unsigned long prate; 483 + unsigned m; 484 + 485 + if (dss.dpll4_m4_ck == NULL) { 486 + /* 487 + * TODO: dss1_fclk can be changed on OMAP2, but the available 488 + * dividers are not continuous. We just use the pre-set rate for 489 + * now. 490 + */ 491 + fck = clk_get_rate(dss.dss_clk); 492 + fckd = 1; 493 + return func(fckd, fck, data); 494 + } 495 + 496 + fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 497 + fckd_hw_max = dss.feat->fck_div_max; 498 + 499 + m = dss.feat->dss_fck_multiplier; 500 + prate = dss_get_dpll4_rate(); 501 + 502 + fck_min = fck_min ? fck_min : 1; 503 + 504 + fckd_start = min(prate * m / fck_min, fckd_hw_max); 505 + fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul); 506 + 507 + for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { 508 + fck = prate / fckd * m; 509 + 510 + if (func(fckd, fck, data)) 511 + return true; 512 + } 513 + 514 + return false; 515 + } 516 + 476 517 int dss_set_clock_div(struct dss_clock_info *cinfo) 477 518 { 478 519 if (dss.dpll4_m4_ck) { ··· 523 482 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 524 483 DSSDBG("dpll4_m4 = %ld\n", prate); 525 484 526 - r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 485 + r = clk_set_rate(dss.dpll4_m4_ck, 486 + DIV_ROUND_UP(prate, cinfo->fck_div)); 527 487 if (r) 528 488 return r; 529 489 } else { ··· 534 492 535 493 dss.dss_clk_rate = clk_get_rate(dss.dss_clk); 536 494 537 - WARN_ONCE(dss.dss_clk_rate != cinfo->fck, "clk rate mismatch"); 495 + WARN_ONCE(dss.dss_clk_rate != cinfo->fck, 496 + "clk rate mismatch: %lu != %lu", dss.dss_clk_rate, 497 + cinfo->fck); 538 498 539 499 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 540 500 ··· 582 538 r = dss_set_clock_div(&dss_cinfo); 583 539 if (r) 584 540 return r; 585 - 586 - return 0; 587 - } 588 - 589 - int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, 590 - struct dispc_clock_info *dispc_cinfo) 591 - { 592 - unsigned long prate; 593 - struct dss_clock_info best_dss; 594 - struct dispc_clock_info best_dispc; 595 - 596 - unsigned long fck, max_dss_fck; 597 - 598 - u16 fck_div; 599 - 600 - int match = 0; 601 - int min_fck_per_pck; 602 - 603 - prate = dss_get_dpll4_rate(); 604 - 605 - max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 606 - 607 - fck = clk_get_rate(dss.dss_clk); 608 - if (req_pck == dss.cache_req_pck && prate == dss.cache_prate && 609 - dss.cache_dss_cinfo.fck == fck) { 610 - DSSDBG("dispc clock info found from cache.\n"); 611 - *dss_cinfo = dss.cache_dss_cinfo; 612 - *dispc_cinfo = dss.cache_dispc_cinfo; 613 - return 0; 614 - } 615 - 616 - min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 617 - 618 - if (min_fck_per_pck && 619 - req_pck * min_fck_per_pck > max_dss_fck) { 620 - DSSERR("Requested pixel clock not possible with the current " 621 - "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 622 - "the constraint off.\n"); 623 - min_fck_per_pck = 0; 624 - } 625 - 626 - retry: 627 - memset(&best_dss, 0, sizeof(best_dss)); 628 - memset(&best_dispc, 0, sizeof(best_dispc)); 629 - 630 - if (dss.dpll4_m4_ck == NULL) { 631 - struct dispc_clock_info cur_dispc; 632 - /* XXX can we change the clock on omap2? */ 633 - fck = clk_get_rate(dss.dss_clk); 634 - fck_div = 1; 635 - 636 - dispc_find_clk_divs(req_pck, fck, &cur_dispc); 637 - match = 1; 638 - 639 - best_dss.fck = fck; 640 - best_dss.fck_div = fck_div; 641 - 642 - best_dispc = cur_dispc; 643 - 644 - goto found; 645 - } else { 646 - for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) { 647 - struct dispc_clock_info cur_dispc; 648 - 649 - fck = prate / fck_div * dss.feat->dss_fck_multiplier; 650 - 651 - if (fck > max_dss_fck) 652 - continue; 653 - 654 - if (min_fck_per_pck && 655 - fck < req_pck * min_fck_per_pck) 656 - continue; 657 - 658 - match = 1; 659 - 660 - dispc_find_clk_divs(req_pck, fck, &cur_dispc); 661 - 662 - if (abs(cur_dispc.pck - req_pck) < 663 - abs(best_dispc.pck - req_pck)) { 664 - 665 - best_dss.fck = fck; 666 - best_dss.fck_div = fck_div; 667 - 668 - best_dispc = cur_dispc; 669 - 670 - if (cur_dispc.pck == req_pck) 671 - goto found; 672 - } 673 - } 674 - } 675 - 676 - found: 677 - if (!match) { 678 - if (min_fck_per_pck) { 679 - DSSERR("Could not find suitable clock settings.\n" 680 - "Turning FCK/PCK constraint off and" 681 - "trying again.\n"); 682 - min_fck_per_pck = 0; 683 - goto retry; 684 - } 685 - 686 - DSSERR("Could not find suitable clock settings.\n"); 687 - 688 - return -EINVAL; 689 - } 690 - 691 - if (dss_cinfo) 692 - *dss_cinfo = best_dss; 693 - if (dispc_cinfo) 694 - *dispc_cinfo = best_dispc; 695 - 696 - dss.cache_req_pck = req_pck; 697 - dss.cache_prate = prate; 698 - dss.cache_dss_cinfo = best_dss; 699 - dss.cache_dispc_cinfo = best_dispc; 700 541 701 542 return 0; 702 543 } ··· 696 767 static int dss_get_clocks(void) 697 768 { 698 769 struct clk *clk; 699 - int r; 700 770 701 - clk = clk_get(&dss.pdev->dev, "fck"); 771 + clk = devm_clk_get(&dss.pdev->dev, "fck"); 702 772 if (IS_ERR(clk)) { 703 773 DSSERR("can't get clock fck\n"); 704 - r = PTR_ERR(clk); 705 - goto err; 774 + return PTR_ERR(clk); 706 775 } 707 776 708 777 dss.dss_clk = clk; ··· 709 782 clk = clk_get(NULL, dss.feat->clk_name); 710 783 if (IS_ERR(clk)) { 711 784 DSSERR("Failed to get %s\n", dss.feat->clk_name); 712 - r = PTR_ERR(clk); 713 - goto err; 785 + return PTR_ERR(clk); 714 786 } 715 787 } else { 716 788 clk = NULL; ··· 718 792 dss.dpll4_m4_ck = clk; 719 793 720 794 return 0; 721 - 722 - err: 723 - if (dss.dss_clk) 724 - clk_put(dss.dss_clk); 725 - if (dss.dpll4_m4_ck) 726 - clk_put(dss.dpll4_m4_ck); 727 - 728 - return r; 729 795 } 730 796 731 797 static void dss_put_clocks(void) 732 798 { 733 799 if (dss.dpll4_m4_ck) 734 800 clk_put(dss.dpll4_m4_ck); 735 - clk_put(dss.dss_clk); 736 801 } 737 802 738 803 static int dss_runtime_get(void)
+21 -15
drivers/video/omap2/dss/dss.h
··· 268 268 unsigned long dss_get_dpll4_rate(void); 269 269 int dss_calc_clock_rates(struct dss_clock_info *cinfo); 270 270 int dss_set_clock_div(struct dss_clock_info *cinfo); 271 - int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, 272 - struct dispc_clock_info *dispc_cinfo); 271 + 272 + typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data); 273 + bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data); 273 274 274 275 /* SDI */ 275 276 int sdi_init_platform_driver(void) __init; ··· 293 292 void dsi_irq_handler(void); 294 293 u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); 295 294 295 + unsigned long dsi_get_pll_clkin(struct platform_device *dsidev); 296 + 297 + typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint, 298 + unsigned long pll, void *data); 299 + typedef bool (*dsi_hsdiv_calc_func)(int regm_dispc, unsigned long dispc, 300 + void *data); 301 + bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll, 302 + unsigned long out_min, dsi_hsdiv_calc_func func, void *data); 303 + bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin, 304 + unsigned long pll_min, unsigned long pll_max, 305 + dsi_pll_calc_func func, void *data); 306 + 296 307 unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); 297 308 int dsi_pll_set_clock_div(struct platform_device *dsidev, 298 309 struct dsi_clock_info *cinfo); 299 - int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, 300 - unsigned long req_pck, struct dsi_clock_info *cinfo, 301 - struct dispc_clock_info *dispc_cinfo); 302 310 int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, 303 311 bool enable_hsdiv); 304 312 void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); ··· 334 324 } 335 325 static inline int dsi_pll_set_clock_div(struct platform_device *dsidev, 336 326 struct dsi_clock_info *cinfo) 337 - { 338 - WARN("%s: DSI not compiled in\n", __func__); 339 - return -ENODEV; 340 - } 341 - static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, 342 - unsigned long req_pck, 343 - struct dsi_clock_info *dsi_cinfo, 344 - struct dispc_clock_info *dispc_cinfo) 345 327 { 346 328 WARN("%s: DSI not compiled in\n", __func__); 347 329 return -ENODEV; ··· 378 376 void dispc_enable_gamma_table(bool enable); 379 377 void dispc_set_loadmode(enum omap_dss_load_mode mode); 380 378 379 + typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck, 380 + unsigned long pck, void *data); 381 + bool dispc_div_calc(unsigned long dispc, 382 + unsigned long pck_min, unsigned long pck_max, 383 + dispc_div_calc_func func, void *data); 384 + 381 385 bool dispc_mgr_timings_ok(enum omap_channel channel, 382 386 const struct omap_video_timings *timings); 383 387 unsigned long dispc_fclk_rate(void); 384 - void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck, 385 - struct dispc_clock_info *cinfo); 386 388 int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 387 389 struct dispc_clock_info *cinfo); 388 390
+4 -4
drivers/video/omap2/dss/dss_features.c
··· 414 414 }; 415 415 416 416 static const struct dss_param_range omap2_dss_param_range[] = { 417 - [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, 417 + [FEAT_PARAM_DSS_FCK] = { 0, 133000000 }, 418 418 [FEAT_PARAM_DSS_PCD] = { 2, 255 }, 419 419 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 }, 420 420 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 }, ··· 459 459 }; 460 460 461 461 static const struct dss_param_range omap5_dss_param_range[] = { 462 - [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, 462 + [FEAT_PARAM_DSS_FCK] = { 0, 209250000 }, 463 463 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 464 464 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, 465 465 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, 466 466 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, 467 467 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, 468 - [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, 468 + [FEAT_PARAM_DSIPLL_FINT] = { 150000, 52000000 }, 469 469 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 470 - [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, 470 + [FEAT_PARAM_DSI_FCK] = { 0, 209250000 }, 471 471 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 472 472 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 473 473 };
+9 -26
drivers/video/omap2/dss/hdmi.c
··· 472 472 * Input clock is predivided by N + 1 473 473 * out put of which is reference clk 474 474 */ 475 - if (dssdev->clocks.hdmi.regn == 0) 476 - pi->regn = HDMI_DEFAULT_REGN; 477 - else 478 - pi->regn = dssdev->clocks.hdmi.regn; 475 + 476 + pi->regn = HDMI_DEFAULT_REGN; 479 477 480 478 refclk = clkin / pi->regn; 481 479 482 - if (dssdev->clocks.hdmi.regm2 == 0) 483 - pi->regm2 = HDMI_DEFAULT_REGM2; 484 - else 485 - pi->regm2 = dssdev->clocks.hdmi.regm2; 480 + pi->regm2 = HDMI_DEFAULT_REGM2; 486 481 487 482 /* 488 483 * multiplier is pixel_clk/ref_clk ··· 799 804 { 800 805 struct clk *clk; 801 806 802 - clk = clk_get(&pdev->dev, "sys_clk"); 807 + clk = devm_clk_get(&pdev->dev, "sys_clk"); 803 808 if (IS_ERR(clk)) { 804 809 DSSERR("can't get sys_clk\n"); 805 810 return PTR_ERR(clk); ··· 808 813 hdmi.sys_clk = clk; 809 814 810 815 return 0; 811 - } 812 - 813 - static void hdmi_put_clocks(void) 814 - { 815 - if (hdmi.sys_clk) 816 - clk_put(hdmi.sys_clk); 817 816 } 818 817 819 818 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) ··· 1006 1017 hdmi.ls_oe_gpio = priv->ls_oe_gpio; 1007 1018 hdmi.hpd_gpio = priv->hpd_gpio; 1008 1019 1009 - dssdev->channel = OMAP_DSS_CHANNEL_DIGIT; 1010 - 1011 1020 r = hdmi_init_display(dssdev); 1012 1021 if (r) { 1013 1022 DSSERR("device %s init failed: %d\n", dssdev->name, r); ··· 1038 1051 out->pdev = pdev; 1039 1052 out->id = OMAP_DSS_OUTPUT_HDMI; 1040 1053 out->type = OMAP_DISPLAY_TYPE_HDMI; 1054 + out->name = "hdmi.0"; 1055 + out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 1041 1056 1042 1057 dss_register_output(out); 1043 1058 } ··· 1086 1097 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1087 1098 hdmi.ip_data.phy_offset = HDMI_PHY; 1088 1099 1100 + hdmi_init_output(pdev); 1101 + 1089 1102 r = hdmi_panel_init(); 1090 1103 if (r) { 1091 1104 DSSERR("can't init panel\n"); 1092 - goto err_panel_init; 1105 + return r; 1093 1106 } 1094 1107 1095 1108 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1096 1109 1097 - hdmi_init_output(pdev); 1098 - 1099 1110 hdmi_probe_pdata(pdev); 1100 1111 1101 1112 return 0; 1102 - 1103 - err_panel_init: 1104 - hdmi_put_clocks(); 1105 - return r; 1106 1113 } 1107 1114 1108 1115 static int __exit hdmi_remove_child(struct device *dev, void *data) ··· 1119 1134 hdmi_uninit_output(pdev); 1120 1135 1121 1136 pm_runtime_disable(&pdev->dev); 1122 - 1123 - hdmi_put_clocks(); 1124 1137 1125 1138 return 0; 1126 1139 }
+1
drivers/video/omap2/dss/output.c
··· 113 113 114 114 return NULL; 115 115 } 116 + EXPORT_SYMBOL(omap_dss_get_output); 116 117 117 118 static const struct dss_mgr_ops *dss_mgr_ops; 118 119
+2
drivers/video/omap2/dss/rfbi.c
··· 1025 1025 out->pdev = pdev; 1026 1026 out->id = OMAP_DSS_OUTPUT_DBI; 1027 1027 out->type = OMAP_DISPLAY_TYPE_DBI; 1028 + out->name = "rfbi.0"; 1029 + out->dispc_channel = OMAP_DSS_CHANNEL_LCD; 1028 1030 1029 1031 dss_register_output(out); 1030 1032 }
+69 -1
drivers/video/omap2/dss/sdi.c
··· 41 41 struct omap_dss_output output; 42 42 } sdi; 43 43 44 + struct sdi_clk_calc_ctx { 45 + unsigned long pck_min, pck_max; 46 + 47 + struct dss_clock_info dss_cinfo; 48 + struct dispc_clock_info dispc_cinfo; 49 + }; 50 + 51 + static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, 52 + unsigned long pck, void *data) 53 + { 54 + struct sdi_clk_calc_ctx *ctx = data; 55 + 56 + ctx->dispc_cinfo.lck_div = lckd; 57 + ctx->dispc_cinfo.pck_div = pckd; 58 + ctx->dispc_cinfo.lck = lck; 59 + ctx->dispc_cinfo.pck = pck; 60 + 61 + return true; 62 + } 63 + 64 + static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) 65 + { 66 + struct sdi_clk_calc_ctx *ctx = data; 67 + 68 + ctx->dss_cinfo.fck = fck; 69 + ctx->dss_cinfo.fck_div = fckd; 70 + 71 + return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, 72 + dpi_calc_dispc_cb, ctx); 73 + } 74 + 75 + static int sdi_calc_clock_div(unsigned long pclk, 76 + struct dss_clock_info *dss_cinfo, 77 + struct dispc_clock_info *dispc_cinfo) 78 + { 79 + int i; 80 + struct sdi_clk_calc_ctx ctx; 81 + 82 + /* 83 + * DSS fclk gives us very few possibilities, so finding a good pixel 84 + * clock may not be possible. We try multiple times to find the clock, 85 + * each time widening the pixel clock range we look for, up to 86 + * +/- 1MHz. 87 + */ 88 + 89 + for (i = 0; i < 10; ++i) { 90 + bool ok; 91 + 92 + memset(&ctx, 0, sizeof(ctx)); 93 + if (pclk > 1000 * i * i * i) 94 + ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu); 95 + else 96 + ctx.pck_min = 0; 97 + ctx.pck_max = pclk + 1000 * i * i * i; 98 + 99 + ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx); 100 + if (ok) { 101 + *dss_cinfo = ctx.dss_cinfo; 102 + *dispc_cinfo = ctx.dispc_cinfo; 103 + return 0; 104 + } 105 + } 106 + 107 + return -EINVAL; 108 + } 109 + 44 110 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 45 111 { 46 112 struct omap_overlay_manager *mgr = dssdev->output->manager; ··· 154 88 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 155 89 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 156 90 157 - r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); 91 + r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); 158 92 if (r) 159 93 goto err_calc_clock_div; 160 94 ··· 344 278 out->pdev = pdev; 345 279 out->id = OMAP_DSS_OUTPUT_SDI; 346 280 out->type = OMAP_DISPLAY_TYPE_SDI; 281 + out->name = "sdi.0"; 282 + out->dispc_channel = OMAP_DSS_CHANNEL_LCD; 347 283 348 284 dss_register_output(out); 349 285 }
+3 -11
drivers/video/omap2/dss/venc.c
··· 712 712 struct clk *clk; 713 713 714 714 if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) { 715 - clk = clk_get(&pdev->dev, "tv_dac_clk"); 715 + clk = devm_clk_get(&pdev->dev, "tv_dac_clk"); 716 716 if (IS_ERR(clk)) { 717 717 DSSERR("can't get tv_dac_clk\n"); 718 718 return PTR_ERR(clk); ··· 724 724 venc.tv_dac_clk = clk; 725 725 726 726 return 0; 727 - } 728 - 729 - static void venc_put_clocks(void) 730 - { 731 - if (venc.tv_dac_clk) 732 - clk_put(venc.tv_dac_clk); 733 727 } 734 728 735 729 static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev) ··· 771 777 772 778 dss_copy_device_pdata(dssdev, plat_dssdev); 773 779 774 - dssdev->channel = OMAP_DSS_CHANNEL_DIGIT; 775 - 776 780 r = venc_init_display(dssdev); 777 781 if (r) { 778 782 DSSERR("device %s init failed: %d\n", dssdev->name, r); ··· 802 810 out->pdev = pdev; 803 811 out->id = OMAP_DSS_OUTPUT_VENC; 804 812 out->type = OMAP_DISPLAY_TYPE_VENC; 813 + out->name = "venc.0"; 814 + out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 805 815 806 816 dss_register_output(out); 807 817 } ··· 871 877 err_panel_init: 872 878 err_runtime_get: 873 879 pm_runtime_disable(&pdev->dev); 874 - venc_put_clocks(); 875 880 return r; 876 881 } 877 882 ··· 888 895 venc_uninit_output(pdev); 889 896 890 897 pm_runtime_disable(&pdev->dev); 891 - venc_put_clocks(); 892 898 893 899 return 0; 894 900 }
+1 -1
drivers/video/omap2/omapfb/omapfb-main.c
··· 2388 2388 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; 2389 2389 struct omap_dss_output *out = dssdev->output; 2390 2390 2391 - mgr = omap_dss_get_overlay_manager(dssdev->channel); 2391 + mgr = omap_dss_get_overlay_manager(out->dispc_channel); 2392 2392 2393 2393 if (!mgr || !out) 2394 2394 continue;
+42 -44
include/video/omapdss.h
··· 257 257 258 258 /* DSI */ 259 259 260 + enum omap_dss_dsi_trans_mode { 261 + /* Sync Pulses: both sync start and end packets sent */ 262 + OMAP_DSS_DSI_PULSE_MODE, 263 + /* Sync Events: only sync start packets sent */ 264 + OMAP_DSS_DSI_EVENT_MODE, 265 + /* Burst: only sync start packets sent, pixels are time compressed */ 266 + OMAP_DSS_DSI_BURST_MODE, 267 + }; 268 + 260 269 struct omap_dss_dsi_videomode_timings { 270 + unsigned long hsclk; 271 + 272 + unsigned ndl; 273 + unsigned bitspp; 274 + 275 + /* pixels */ 276 + u16 hact; 277 + /* lines */ 278 + u16 vact; 279 + 261 280 /* DSI video mode blanking data */ 262 281 /* Unit: byte clock cycles */ 282 + u16 hss; 263 283 u16 hsa; 284 + u16 hse; 264 285 u16 hfp; 265 286 u16 hbp; 266 287 /* Unit: line clocks */ ··· 295 274 int hbp_blanking_mode; 296 275 int hfp_blanking_mode; 297 276 298 - /* Video port sync events */ 299 - bool vp_vsync_end; 300 - bool vp_hsync_end; 277 + enum omap_dss_dsi_trans_mode trans_mode; 301 278 302 279 bool ddr_clk_always_on; 303 280 int window_sync; 281 + }; 282 + 283 + struct omap_dss_dsi_config { 284 + enum omap_dss_dsi_mode mode; 285 + enum omap_dss_dsi_pixel_format pixel_format; 286 + const struct omap_video_timings *timings; 287 + 288 + unsigned long hs_clk_min, hs_clk_max; 289 + unsigned long lp_clk_min, lp_clk_max; 290 + 291 + bool ddr_clk_always_on; 292 + enum omap_dss_dsi_trans_mode trans_mode; 304 293 }; 305 294 306 295 void dsi_bus_lock(struct omap_dss_device *dssdev); ··· 572 541 struct omap_dss_output { 573 542 struct list_head list; 574 543 544 + const char *name; 545 + 575 546 /* display type supported by the output */ 576 547 enum omap_display_type type; 548 + 549 + /* DISPC channel for this output */ 550 + enum omap_channel dispc_channel; 577 551 578 552 /* output instance */ 579 553 enum omap_dss_output_id id; ··· 597 561 598 562 enum omap_display_type type; 599 563 564 + /* obsolete, to be removed */ 600 565 enum omap_channel channel; 601 566 602 567 union { ··· 628 591 } phy; 629 592 630 593 struct { 631 - struct { 632 - struct { 633 - u16 lck_div; 634 - u16 pck_div; 635 - enum omap_dss_clk_source lcd_clk_src; 636 - } channel; 637 - 638 - enum omap_dss_clk_source dispc_fclk_src; 639 - } dispc; 640 - 641 - struct { 642 - /* regn is one greater than TRM's REGN value */ 643 - u16 regn; 644 - u16 regm; 645 - u16 regm_dispc; 646 - u16 regm_dsi; 647 - 648 - u16 lp_clk_div; 649 - enum omap_dss_clk_source dsi_fclk_src; 650 - } dsi; 651 - 652 - struct { 653 - /* regn is one greater than TRM's REGN value */ 654 - u16 regn; 655 - u16 regm2; 656 - } hdmi; 657 - } clocks; 658 - 659 - struct { 660 594 struct omap_video_timings timings; 661 595 662 596 enum omap_dss_dsi_pixel_format dsi_pix_fmt; 663 597 enum omap_dss_dsi_mode dsi_mode; 664 - struct omap_dss_dsi_videomode_timings dsi_vm_timings; 665 598 } panel; 666 599 667 600 struct { ··· 836 829 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, 837 830 bool enable); 838 831 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); 839 - void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, 840 - struct omap_video_timings *timings); 841 - void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h); 842 - void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, 843 - enum omap_dss_dsi_pixel_format fmt); 844 - void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, 845 - enum omap_dss_dsi_mode mode); 846 - void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, 847 - struct omap_dss_dsi_videomode_timings *timings); 832 + int omapdss_dsi_set_config(struct omap_dss_device *dssdev, 833 + const struct omap_dss_dsi_config *config); 848 834 849 835 int omap_dsi_update(struct omap_dss_device *dssdev, int channel, 850 836 void (*callback)(int, void *), void *data); ··· 846 846 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); 847 847 int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, 848 848 const struct omap_dsi_pin_config *pin_cfg); 849 - int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, 850 - unsigned long ddr_clk, unsigned long lp_clk); 851 849 852 850 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); 853 851 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,