Lines Matching +full:display +full:- +full:timings

1 // SPDX-License-Identifier: GPL-2.0-only
19 #include <media/v4l2-device.h>
38 MODULE_PARM_DESC(debug, "Debug level 0-1");
40 MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
45 * vpbe_current_encoder_info - Get config info for current encoder
53 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_current_encoder_info()
54 int index = vpbe_dev->current_sd_index; in vpbe_current_encoder_info()
56 return ((index == 0) ? &cfg->venc : in vpbe_current_encoder_info()
57 &cfg->ext_encoders[index-1]); in vpbe_current_encoder_info()
61 * vpbe_find_encoder_sd_index - Given a name find encoder sd index
71 char *encoder_name = cfg->outputs[index].subdev_name; in vpbe_find_encoder_sd_index()
75 if (!strcmp(encoder_name, cfg->venc.module_name)) in vpbe_find_encoder_sd_index()
78 for (i = 0; i < cfg->num_ext_encoders; i++) { in vpbe_find_encoder_sd_index()
80 cfg->ext_encoders[i].module_name)) in vpbe_find_encoder_sd_index()
84 return -EINVAL; in vpbe_find_encoder_sd_index()
88 * vpbe_enum_outputs - enumerate outputs
92 * Enumerates the outputs available at the vpbe display
93 * returns the status, -EINVAL if end of output list
98 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_enum_outputs()
99 unsigned int temp_index = output->index; in vpbe_enum_outputs()
101 if (temp_index >= cfg->num_outputs) in vpbe_enum_outputs()
102 return -EINVAL; in vpbe_enum_outputs()
104 *output = cfg->outputs[temp_index].output; in vpbe_enum_outputs()
105 output->index = temp_index; in vpbe_enum_outputs()
113 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_get_mode_info()
119 return -EINVAL; in vpbe_get_mode_info()
121 for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) { in vpbe_get_mode_info()
122 var = cfg->outputs[curr_output].modes[i]; in vpbe_get_mode_info()
124 vpbe_dev->current_timings = var; in vpbe_get_mode_info()
129 return -EINVAL; in vpbe_get_mode_info()
136 return -EINVAL; in vpbe_get_current_mode_info()
138 *mode_info = vpbe_dev->current_timings; in vpbe_get_current_mode_info()
147 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_get_std_info()
149 int curr_output = vpbe_dev->current_out_index; in vpbe_get_std_info()
152 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) { in vpbe_get_std_info()
153 var = cfg->outputs[curr_output].modes[i]; in vpbe_get_std_info()
156 vpbe_dev->current_timings = var; in vpbe_get_std_info()
161 return -EINVAL; in vpbe_get_std_info()
167 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_get_std_info_by_name()
169 int curr_output = vpbe_dev->current_out_index; in vpbe_get_std_info_by_name()
172 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) { in vpbe_get_std_info_by_name()
173 var = cfg->outputs[curr_output].modes[i]; in vpbe_get_std_info_by_name()
175 vpbe_dev->current_timings = var; in vpbe_get_std_info_by_name()
180 return -EINVAL; in vpbe_get_std_info_by_name()
184 * vpbe_set_output - Set output
194 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_set_output()
195 struct venc_platform_data *venc_device = vpbe_dev->venc_device; in vpbe_set_output()
200 if (index >= cfg->num_outputs) in vpbe_set_output()
201 return -EINVAL; in vpbe_set_output()
203 mutex_lock(&vpbe_dev->lock); in vpbe_set_output()
205 sd_index = vpbe_dev->current_sd_index; in vpbe_set_output()
206 enc_out_index = cfg->outputs[index].output.index; in vpbe_set_output()
216 if (strcmp(curr_enc_info->module_name, in vpbe_set_output()
217 cfg->outputs[index].subdev_name)) { in vpbe_set_output()
221 ret = -EINVAL; in vpbe_set_output()
225 ret = venc_device->setup_if_config(cfg->outputs[index].if_params); in vpbe_set_output()
231 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, in vpbe_set_output()
241 * arch/arm/mach-davinci/board-dm355-evm.setup file for the external in vpbe_set_output()
245 cfg->outputs[index].default_mode, index); in vpbe_set_output()
247 struct osd_state *osd_device = vpbe_dev->osd_device; in vpbe_set_output()
249 osd_device->ops.set_left_margin(osd_device, in vpbe_set_output()
250 vpbe_dev->current_timings.left_margin); in vpbe_set_output()
251 osd_device->ops.set_top_margin(osd_device, in vpbe_set_output()
252 vpbe_dev->current_timings.upper_margin); in vpbe_set_output()
253 vpbe_dev->current_sd_index = sd_index; in vpbe_set_output()
254 vpbe_dev->current_out_index = index; in vpbe_set_output()
257 mutex_unlock(&vpbe_dev->lock); in vpbe_set_output()
263 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_set_default_output()
266 for (i = 0; i < cfg->num_outputs; i++) { in vpbe_set_default_output()
268 cfg->outputs[i].output.name)) { in vpbe_set_default_output()
272 vpbe_dev->current_out_index = i; in vpbe_set_default_output()
280 * vpbe_get_output - Get output
287 return vpbe_dev->current_out_index; in vpbe_get_output()
291 * vpbe_s_dv_timings - Set the given preset timings in the encoder
293 * Sets the timings if supported by the current encoder. Return the status.
294 * 0 - success & -EINVAL on error
299 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_s_dv_timings()
300 int out_index = vpbe_dev->current_out_index; in vpbe_s_dv_timings()
301 struct vpbe_output *output = &cfg->outputs[out_index]; in vpbe_s_dv_timings()
302 int sd_index = vpbe_dev->current_sd_index; in vpbe_s_dv_timings()
306 if (!(cfg->outputs[out_index].output.capabilities & in vpbe_s_dv_timings()
308 return -ENODATA; in vpbe_s_dv_timings()
310 for (i = 0; i < output->num_modes; i++) { in vpbe_s_dv_timings()
311 if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS && in vpbe_s_dv_timings()
312 !memcmp(&output->modes[i].dv_timings, in vpbe_s_dv_timings()
316 if (i >= output->num_modes) in vpbe_s_dv_timings()
317 return -EINVAL; in vpbe_s_dv_timings()
318 vpbe_dev->current_timings = output->modes[i]; in vpbe_s_dv_timings()
319 mutex_lock(&vpbe_dev->lock); in vpbe_s_dv_timings()
321 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, in vpbe_s_dv_timings()
323 if (!ret && vpbe_dev->amp) { in vpbe_s_dv_timings()
325 ret = v4l2_subdev_call(vpbe_dev->amp, video, in vpbe_s_dv_timings()
330 struct osd_state *osd_device = vpbe_dev->osd_device; in vpbe_s_dv_timings()
332 osd_device->ops.set_left_margin(osd_device, in vpbe_s_dv_timings()
333 vpbe_dev->current_timings.left_margin); in vpbe_s_dv_timings()
334 osd_device->ops.set_top_margin(osd_device, in vpbe_s_dv_timings()
335 vpbe_dev->current_timings.upper_margin); in vpbe_s_dv_timings()
337 mutex_unlock(&vpbe_dev->lock); in vpbe_s_dv_timings()
343 * vpbe_g_dv_timings - Get the timings in the current encoder
345 * Get the timings in the current encoder. Return the status. 0 - success
346 * -EINVAL on error
351 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_g_dv_timings()
352 int out_index = vpbe_dev->current_out_index; in vpbe_g_dv_timings()
354 if (!(cfg->outputs[out_index].output.capabilities & in vpbe_g_dv_timings()
356 return -ENODATA; in vpbe_g_dv_timings()
358 if (vpbe_dev->current_timings.timings_type & in vpbe_g_dv_timings()
360 *dv_timings = vpbe_dev->current_timings.dv_timings; in vpbe_g_dv_timings()
364 return -EINVAL; in vpbe_g_dv_timings()
368 * vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
370 * Get the timings in the current encoder. Return the status. 0 - success
371 * -EINVAL on error
374 struct v4l2_enum_dv_timings *timings) in vpbe_enum_dv_timings() argument
376 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_enum_dv_timings()
377 int out_index = vpbe_dev->current_out_index; in vpbe_enum_dv_timings()
378 struct vpbe_output *output = &cfg->outputs[out_index]; in vpbe_enum_dv_timings()
382 if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS)) in vpbe_enum_dv_timings()
383 return -ENODATA; in vpbe_enum_dv_timings()
385 for (i = 0; i < output->num_modes; i++) { in vpbe_enum_dv_timings()
386 if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) { in vpbe_enum_dv_timings()
387 if (j == timings->index) in vpbe_enum_dv_timings()
393 if (i == output->num_modes) in vpbe_enum_dv_timings()
394 return -EINVAL; in vpbe_enum_dv_timings()
395 timings->timings = output->modes[i].dv_timings; in vpbe_enum_dv_timings()
400 * vpbe_s_std - Set the given standard in the encoder
403 * 0 - success & -EINVAL on error
407 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_s_std()
408 int out_index = vpbe_dev->current_out_index; in vpbe_s_std()
409 int sd_index = vpbe_dev->current_sd_index; in vpbe_s_std()
412 if (!(cfg->outputs[out_index].output.capabilities & in vpbe_s_std()
414 return -ENODATA; in vpbe_s_std()
420 mutex_lock(&vpbe_dev->lock); in vpbe_s_std()
422 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, in vpbe_s_std()
426 struct osd_state *osd_device = vpbe_dev->osd_device; in vpbe_s_std()
428 osd_device->ops.set_left_margin(osd_device, in vpbe_s_std()
429 vpbe_dev->current_timings.left_margin); in vpbe_s_std()
430 osd_device->ops.set_top_margin(osd_device, in vpbe_s_std()
431 vpbe_dev->current_timings.upper_margin); in vpbe_s_std()
433 mutex_unlock(&vpbe_dev->lock); in vpbe_s_std()
439 * vpbe_g_std - Get the standard in the current encoder
441 * Get the standard in the current encoder. Return the status. 0 - success
442 * -EINVAL on error
446 struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings; in vpbe_g_std()
447 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_g_std()
448 int out_index = vpbe_dev->current_out_index; in vpbe_g_std()
450 if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD)) in vpbe_g_std()
451 return -ENODATA; in vpbe_g_std()
453 if (cur_timings->timings_type & VPBE_ENC_STD) { in vpbe_g_std()
454 *std_id = cur_timings->std_id; in vpbe_g_std()
458 return -EINVAL; in vpbe_g_std()
462 * vpbe_set_mode - Set mode in the current encoder using mode info
464 * Use the mode string to decide what timings to set in the encoder
466 * timings by specifying a string to indicate the timings.
472 struct vpbe_config *cfg = vpbe_dev->cfg; in vpbe_set_mode()
475 int out_index = vpbe_dev->current_out_index; in vpbe_set_mode()
478 if (!mode_info || !mode_info->name) in vpbe_set_mode()
479 return -EINVAL; in vpbe_set_mode()
481 for (i = 0; i < cfg->outputs[out_index].num_modes; i++) { in vpbe_set_mode()
482 if (!strcmp(mode_info->name, in vpbe_set_mode()
483 cfg->outputs[out_index].modes[i].name)) { in vpbe_set_mode()
484 preset_mode = &cfg->outputs[out_index].modes[i]; in vpbe_set_mode()
486 * it may be one of the 3 timings type. Check and in vpbe_set_mode()
489 if (preset_mode->timings_type & VPBE_ENC_STD) in vpbe_set_mode()
491 preset_mode->std_id); in vpbe_set_mode()
492 if (preset_mode->timings_type & in vpbe_set_mode()
495 preset_mode->dv_timings; in vpbe_set_mode()
503 return -EINVAL; in vpbe_set_mode()
505 mutex_lock(&vpbe_dev->lock); in vpbe_set_mode()
507 osd_device = vpbe_dev->osd_device; in vpbe_set_mode()
508 vpbe_dev->current_timings = *preset_mode; in vpbe_set_mode()
509 osd_device->ops.set_left_margin(osd_device, in vpbe_set_mode()
510 vpbe_dev->current_timings.left_margin); in vpbe_set_mode()
511 osd_device->ops.set_top_margin(osd_device, in vpbe_set_mode()
512 vpbe_dev->current_timings.upper_margin); in vpbe_set_mode()
514 mutex_unlock(&vpbe_dev->lock); in vpbe_set_mode()
527 return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings); in vpbe_set_default_mode()
535 if (strstr(pdev->name, "vpbe-osd")) in platform_device_get()
536 vpbe_dev->osd_device = platform_get_drvdata(pdev); in platform_device_get()
537 if (strstr(pdev->name, "vpbe-venc")) in platform_device_get()
538 vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); in platform_device_get()
544 * vpbe_initialize() - Initialize the vpbe display controller
549 * display controller. This will then registers v4l2 device and the sub
550 * devices and sets a current encoder sub device for display. v4l2 display
551 * device driver is the master and frame buffer display device driver is
552 * the slave. Frame buffer display driver checks the initialized during
574 return -ENODEV; in vpbe_initialize()
577 if (vpbe_dev->initialized) in vpbe_initialize()
580 mutex_lock(&vpbe_dev->lock); in vpbe_initialize()
582 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { in vpbe_initialize()
584 vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac"); in vpbe_initialize()
585 if (IS_ERR(vpbe_dev->dac_clk)) { in vpbe_initialize()
586 ret = PTR_ERR(vpbe_dev->dac_clk); in vpbe_initialize()
589 if (clk_prepare_enable(vpbe_dev->dac_clk)) { in vpbe_initialize()
590 ret = -ENODEV; in vpbe_initialize()
591 clk_put(vpbe_dev->dac_clk); in vpbe_initialize()
600 ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev); in vpbe_initialize()
602 v4l2_err(dev->driver, in vpbe_initialize()
606 v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n"); in vpbe_initialize()
615 vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev, in vpbe_initialize()
616 vpbe_dev->cfg->venc.module_name); in vpbe_initialize()
618 if (!vpbe_dev->venc) { in vpbe_initialize()
619 v4l2_err(&vpbe_dev->v4l2_dev, in vpbe_initialize()
621 ret = -ENODEV; in vpbe_initialize()
625 osd_device = vpbe_dev->osd_device; in vpbe_initialize()
626 if (osd_device->ops.initialize) { in vpbe_initialize()
627 err = osd_device->ops.initialize(osd_device); in vpbe_initialize()
629 v4l2_err(&vpbe_dev->v4l2_dev, in vpbe_initialize()
631 ret = -ENOMEM; in vpbe_initialize()
640 num_encoders = vpbe_dev->cfg->num_ext_encoders + 1; in vpbe_initialize()
641 vpbe_dev->encoders = kmalloc_array(num_encoders, in vpbe_initialize()
642 sizeof(*vpbe_dev->encoders), in vpbe_initialize()
644 if (!vpbe_dev->encoders) { in vpbe_initialize()
645 ret = -ENOMEM; in vpbe_initialize()
649 i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id); in vpbe_initialize()
650 for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) { in vpbe_initialize()
653 enc_subdev = &vpbe_dev->encoders[i]; in vpbe_initialize()
654 *enc_subdev = vpbe_dev->venc; in vpbe_initialize()
657 enc_info = &vpbe_dev->cfg->ext_encoders[i]; in vpbe_initialize()
658 if (enc_info->is_i2c) { in vpbe_initialize()
659 enc_subdev = &vpbe_dev->encoders[i]; in vpbe_initialize()
661 &vpbe_dev->v4l2_dev, i2c_adap, in vpbe_initialize()
662 &enc_info->board_info, NULL); in vpbe_initialize()
664 v4l2_info(&vpbe_dev->v4l2_dev, in vpbe_initialize()
666 enc_info->module_name); in vpbe_initialize()
668 v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s failed to register", in vpbe_initialize()
669 enc_info->module_name); in vpbe_initialize()
670 ret = -ENODEV; in vpbe_initialize()
674 v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders currently not supported"); in vpbe_initialize()
677 if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && in vpbe_initialize()
678 vpbe_dev->cfg->amp) { in vpbe_initialize()
679 amp_info = vpbe_dev->cfg->amp; in vpbe_initialize()
680 if (amp_info->is_i2c) { in vpbe_initialize()
681 vpbe_dev->amp = v4l2_i2c_new_subdev_board( in vpbe_initialize()
682 &vpbe_dev->v4l2_dev, i2c_adap, in vpbe_initialize()
683 &amp_info->board_info, NULL); in vpbe_initialize()
684 if (!vpbe_dev->amp) { in vpbe_initialize()
685 v4l2_err(&vpbe_dev->v4l2_dev, in vpbe_initialize()
687 amp_info->module_name); in vpbe_initialize()
688 ret = -ENODEV; in vpbe_initialize()
691 v4l2_info(&vpbe_dev->v4l2_dev, in vpbe_initialize()
693 amp_info->module_name); in vpbe_initialize()
695 vpbe_dev->amp = NULL; in vpbe_initialize()
696 v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers currently not supported"); in vpbe_initialize()
699 vpbe_dev->amp = NULL; in vpbe_initialize()
703 vpbe_dev->current_sd_index = 0; in vpbe_initialize()
704 vpbe_dev->current_out_index = 0; in vpbe_initialize()
706 mutex_unlock(&vpbe_dev->lock); in vpbe_initialize()
711 v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s", in vpbe_initialize()
719 v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s", in vpbe_initialize()
723 vpbe_dev->initialized = 1; in vpbe_initialize()
728 mutex_lock(&vpbe_dev->lock); in vpbe_initialize()
729 kfree(vpbe_dev->amp); in vpbe_initialize()
731 kfree(vpbe_dev->encoders); in vpbe_initialize()
733 v4l2_device_unregister(&vpbe_dev->v4l2_dev); in vpbe_initialize()
735 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { in vpbe_initialize()
736 clk_disable_unprepare(vpbe_dev->dac_clk); in vpbe_initialize()
737 clk_put(vpbe_dev->dac_clk); in vpbe_initialize()
740 mutex_unlock(&vpbe_dev->lock); in vpbe_initialize()
745 * vpbe_deinitialize() - de-initialize the vpbe display controller
749 * vpbe_master and slave frame buffer devices calls this to de-initialize
750 * the display controller. It is called when master and slave device
751 * driver modules are removed and no longer requires the display controller.
755 v4l2_device_unregister(&vpbe_dev->v4l2_dev); in vpbe_deinitialize()
756 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { in vpbe_deinitialize()
757 clk_disable_unprepare(vpbe_dev->dac_clk); in vpbe_deinitialize()
758 clk_put(vpbe_dev->dac_clk); in vpbe_deinitialize()
761 kfree(vpbe_dev->amp); in vpbe_deinitialize()
762 kfree(vpbe_dev->encoders); in vpbe_deinitialize()
763 vpbe_dev->initialized = 0; in vpbe_deinitialize()
788 if (!pdev->dev.platform_data) { in vpbe_probe()
789 v4l2_err(pdev->dev.driver, "No platform data\n"); in vpbe_probe()
790 return -ENODEV; in vpbe_probe()
792 cfg = pdev->dev.platform_data; in vpbe_probe()
794 if (!cfg->module_name[0] || in vpbe_probe()
795 !cfg->osd.module_name[0] || in vpbe_probe()
796 !cfg->venc.module_name[0]) { in vpbe_probe()
797 v4l2_err(pdev->dev.driver, "vpbe display module names not defined\n"); in vpbe_probe()
798 return -EINVAL; in vpbe_probe()
803 return -ENOMEM; in vpbe_probe()
805 vpbe_dev->cfg = cfg; in vpbe_probe()
806 vpbe_dev->ops = vpbe_dev_ops; in vpbe_probe()
807 vpbe_dev->pdev = &pdev->dev; in vpbe_probe()
809 if (cfg->outputs->num_modes > 0) in vpbe_probe()
810 vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0]; in vpbe_probe()
813 return -ENODEV; in vpbe_probe()
818 mutex_init(&vpbe_dev->lock); in vpbe_probe()