summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2013-05-27 08:37:04 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:04:30 -0400
commita81db00305a18088d827fa2ce7a76ba0e88d6f40 (patch)
treed80053728d1e36a4ac9e1985c2a5807d51a429b3 /drivers/video/tegra/dc/dsi.c
parent454e9969f5036f5ea3e58d6a2b0ad2025026750f (diff)
video: tegra: dsi: Add panel dt support
Incorporate all support required for default pluto panel. Bug 1172236 Change-Id: Iebd3ba490a1d10a97a09ca5e0631241b6f9069bc Signed-off-by: Animesh Kishore <ankishore@nvidia.com> Reviewed-on: http://git-master/r/232781 Reviewed-by: Mrutyunjay Sawant <msawant@nvidia.com> Tested-by: Mrutyunjay Sawant <msawant@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c243
1 files changed, 203 insertions, 40 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 4dd3101eb..9045861bc 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -30,6 +30,8 @@
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/nvhost.h> 31#include <linux/nvhost.h>
32#include <linux/lcm.h> 32#include <linux/lcm.h>
33#include <linux/of_address.h>
34#include <linux/of_gpio.h>
33#include <linux/regulator/consumer.h> 35#include <linux/regulator/consumer.h>
34#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
35 37
@@ -3550,6 +3552,158 @@ static void __tegra_dc_dsi_init(struct tegra_dc *dc)
3550 tegra_dsi_init_sw(dc, dsi); 3552 tegra_dsi_init_sw(dc, dsi);
3551} 3553}
3552 3554
3555struct tegra_dsi_cmd *tegra_dsi_parse_cmd_dt(struct tegra_dc_dsi_data *dsi,
3556 const struct device_node *node,
3557 struct property *prop,
3558 u32 n_cmd)
3559{
3560 struct tegra_dsi_cmd *dsi_cmd, *temp;
3561 u32 *prop_val_ptr = prop->value;
3562 u32 cnt = 0, i = 0;
3563 u8 arg1, arg2;
3564
3565 if (!prop)
3566 return NULL;
3567
3568 dsi_cmd = kzalloc(sizeof(*dsi_cmd) * n_cmd, GFP_KERNEL);
3569 if (!dsi_cmd) {
3570 dev_err(&dsi->dc->ndev->dev,
3571 "dsi: cmd memory allocation failed\n");
3572 return ERR_PTR(-ENOMEM);
3573 }
3574 temp = dsi_cmd;
3575
3576 for (cnt = 0; cnt < n_cmd; cnt++, temp++) {
3577 temp->cmd_type = be32_to_cpu(*prop_val_ptr++);
3578 if (temp->cmd_type == TEGRA_DSI_PACKET_CMD) {
3579 temp->data_id = be32_to_cpu(*prop_val_ptr++);
3580 arg1 = be32_to_cpu(*prop_val_ptr++);
3581 arg2 = be32_to_cpu(*prop_val_ptr++);
3582 prop_val_ptr++; /* skip ecc */
3583 if (temp->data_id == DSI_GENERIC_LONG_WRITE ||
3584 temp->data_id == DSI_DCS_LONG_WRITE ||
3585 temp->data_id == DSI_NULL_PKT_NO_DATA ||
3586 temp->data_id == DSI_BLANKING_PKT_NO_DATA) {
3587 /* long pkt */
3588 temp->sp_len_dly.data_len =
3589 (arg2 << NUMOF_BIT_PER_BYTE) | arg1;
3590 temp->pdata = kzalloc(
3591 temp->sp_len_dly.data_len, GFP_KERNEL);
3592 for (i = 0; i < temp->sp_len_dly.data_len; i++)
3593 (temp->pdata)[i] =
3594 be32_to_cpu(*prop_val_ptr++);
3595 prop_val_ptr += 2; /* skip checksum */
3596 } else {
3597 temp->sp_len_dly.sp.data0 = arg1;
3598 temp->sp_len_dly.sp.data1 = arg2;
3599 }
3600 } else if (temp->cmd_type == TEGRA_DSI_DELAY_MS) {
3601 temp->sp_len_dly.delay_ms =
3602 be32_to_cpu(*prop_val_ptr++);
3603 }
3604 }
3605
3606 return dsi_cmd;
3607}
3608
3609struct device_node *tegra_dsi_panel_detect(void)
3610{
3611 /* TODO: currently only lg 720p panel has dt support */
3612 return of_find_compatible_node(NULL, NULL, "lg,720p-5");
3613}
3614
3615static int tegra_dc_dsi_cp_info_dt(struct tegra_dc_dsi_data *dsi)
3616{
3617 struct device_node *panel_dt_node = tegra_dsi_panel_detect();
3618 struct device_node *dsi_dt_node =
3619 of_find_compatible_node(NULL, NULL, "nvidia,tegra114-dsi");
3620 struct tegra_dsi_out *dsi_pdata = &dsi->info;
3621 int err = 0;
3622
3623 if (!panel_dt_node || !dsi_dt_node) {
3624 dev_info(&dsi->dc->ndev->dev,
3625 "dsi dt support not available\n");
3626 err = -ENOENT;
3627 goto fail;
3628 }
3629
3630 if (panel_dt_node && dsi_dt_node) {
3631 const char *panel_dt_status;
3632 const char *dsi_dt_status;
3633 of_property_read_string(panel_dt_node,
3634 "status", &panel_dt_status);
3635 of_property_read_string(dsi_dt_node,
3636 "status", &dsi_dt_status);
3637 if (strcmp(panel_dt_status, "okay") ||
3638 strcmp(dsi_dt_status, "okay")) {
3639 dev_info(&dsi->dc->ndev->dev,
3640 "dsi dt support disabled\n");
3641 err = -ENOENT;
3642 goto fail;
3643 }
3644 }
3645
3646 of_property_read_u32(panel_dt_node, "nvidia,n-data-lanes",
3647 (u32 *)&dsi_pdata->n_data_lanes);
3648
3649 of_property_read_u32(panel_dt_node, "nvidia,pixel-format",
3650 (u32 *)&dsi_pdata->pixel_format);
3651
3652 of_property_read_u32(panel_dt_node, "nvidia,refresh-rate",
3653 (u32 *)&dsi_pdata->refresh_rate);
3654
3655 of_property_read_u32(panel_dt_node, "nvidia,video-data-type",
3656 (u32 *)&dsi_pdata->video_data_type);
3657
3658 of_property_read_u32(panel_dt_node, "nvidia,video-clock-mode",
3659 (u32 *)&dsi_pdata->video_clock_mode);
3660
3661 of_property_read_u32(panel_dt_node, "nvidia,video-burst-mode",
3662 (u32 *)&dsi_pdata->video_burst_mode);
3663
3664 of_property_read_u32(panel_dt_node, "nvidia,virtual-channel",
3665 (u32 *)&dsi_pdata->virtual_channel);
3666
3667 of_property_read_u32(panel_dt_node, "nvidia,panel-reset",
3668 (u32 *)&dsi_pdata->panel_reset);
3669
3670 dsi_pdata->power_saving_suspend = of_property_read_bool(panel_dt_node,
3671 "nvidia,power-saving-suspend");
3672
3673 of_property_read_u32(dsi_dt_node, "nvidia,controller-vs",
3674 (u32 *)&dsi_pdata->controller_vs);
3675
3676 dsi_pdata->dsi_panel_rst_gpio = of_get_named_gpio(dsi_dt_node,
3677 "nvidia,dsi-panel-rst-gpio", 0);
3678
3679 dsi_pdata->dsi_panel_bl_en_gpio = of_get_named_gpio(dsi_dt_node,
3680 "nvidia,dsi-panel-bl-en-gpio", 0);
3681
3682 dsi_pdata->dsi_panel_bl_pwm_gpio = of_get_named_gpio(dsi_dt_node,
3683 "nvidia,dsi-panel-bl-pwm-gpio", 0);
3684
3685 of_property_read_u32(panel_dt_node, "nvidia,n-init-cmd",
3686 (u32 *)&dsi_pdata->n_init_cmd);
3687
3688 dsi_pdata->dsi_init_cmd = tegra_dsi_parse_cmd_dt(dsi, panel_dt_node,
3689 of_find_property(
3690 panel_dt_node, "nvidia,dsi-init-cmd", NULL),
3691 dsi_pdata->n_init_cmd);
3692 if (IS_ERR_OR_NULL(dsi_pdata->dsi_init_cmd)) {
3693 dev_err(&dsi->dc->ndev->dev,
3694 "dsi: copy init cmd from dt failed\n");
3695 err = PTR_ERR(dsi_pdata->dsi_init_cmd);
3696 goto fail;
3697 }
3698
3699 dsi->dc->pdata->default_out->dsi = &dsi->info;
3700 dsi->dc->out->dsi = &dsi->info;
3701fail:
3702 of_node_put(dsi_dt_node);
3703 of_node_put(panel_dt_node);
3704 return err;
3705}
3706
3553static int tegra_dc_dsi_cp_p_cmd(struct tegra_dsi_cmd *src, 3707static int tegra_dc_dsi_cp_p_cmd(struct tegra_dsi_cmd *src,
3554 struct tegra_dsi_cmd *dst, u16 n_cmd) 3708 struct tegra_dsi_cmd *dst, u16 n_cmd)
3555{ 3709{
@@ -3577,17 +3731,14 @@ free_cmd_pdata:
3577 return -ENOMEM; 3731 return -ENOMEM;
3578} 3732}
3579 3733
3580static int tegra_dc_dsi_cp_info(struct tegra_dc_dsi_data *dsi, 3734static int tegra_dc_dsi_cp_info_board(struct tegra_dc_dsi_data *dsi,
3581 struct tegra_dsi_out *p_dsi) 3735 struct tegra_dsi_out *p_dsi)
3582{ 3736{
3583 struct tegra_dsi_cmd *p_init_cmd; 3737 struct tegra_dsi_cmd *p_init_cmd;
3584 struct tegra_dsi_cmd *p_early_suspend_cmd = NULL; 3738 struct tegra_dsi_cmd *p_early_suspend_cmd = NULL;
3585 struct tegra_dsi_cmd *p_late_resume_cmd = NULL; 3739 struct tegra_dsi_cmd *p_late_resume_cmd = NULL;
3586 struct tegra_dsi_cmd *p_suspend_cmd; 3740 struct tegra_dsi_cmd *p_suspend_cmd;
3587 int err; 3741 int err = 0;
3588
3589 if (p_dsi->n_data_lanes > MAX_DSI_DATA_LANES)
3590 return -EINVAL;
3591 3742
3592 p_init_cmd = kzalloc(sizeof(*p_init_cmd) * 3743 p_init_cmd = kzalloc(sizeof(*p_init_cmd) *
3593 p_dsi->n_init_cmd, GFP_KERNEL); 3744 p_dsi->n_init_cmd, GFP_KERNEL);
@@ -3657,10 +3808,48 @@ static int tegra_dc_dsi_cp_info(struct tegra_dc_dsi_data *dsi,
3657 goto err_free; 3808 goto err_free;
3658 dsi->info.dsi_suspend_cmd = p_suspend_cmd; 3809 dsi->info.dsi_suspend_cmd = p_suspend_cmd;
3659 3810
3811 return 0;
3812err_free:
3813 kfree(p_suspend_cmd);
3814err_free_p_late_resume_cmd:
3815 kfree(p_late_resume_cmd);
3816err_free_p_early_suspend_cmd:
3817 kfree(p_early_suspend_cmd);
3818err_free_init_cmd:
3819 kfree(p_init_cmd);
3820 return err;
3821}
3822
3823static int tegra_dc_dsi_cp_info(struct tegra_dc_dsi_data *dsi)
3824{
3825 int err;
3826
3827 err = tegra_dc_dsi_cp_info_dt(dsi);
3828 if (err < 0) {
3829 /* resort to platform files */
3830 struct tegra_dsi_out *p_dsi;
3831 dev_warn(&dsi->dc->ndev->dev,
3832 "dsi: copy from dt failed, trying platform file\n");
3833 p_dsi = dsi->dc->pdata->default_out->dsi;
3834 if (!p_dsi) {
3835 dev_err(&dsi->dc->ndev->dev,
3836 "dsi: platform dsi data not available\n");
3837 return -EINVAL;
3838 }
3839 err = tegra_dc_dsi_cp_info_board(dsi, p_dsi);
3840 if (err < 0) {
3841 dev_err(&dsi->dc->ndev->dev,
3842 "dsi: copy from platform files failed\n");
3843 return err;
3844 }
3845 }
3846
3847 if (dsi->info.n_data_lanes > MAX_DSI_DATA_LANES)
3848 return -EINVAL;
3849
3660 if (!dsi->info.panel_reset_timeout_msec) 3850 if (!dsi->info.panel_reset_timeout_msec)
3661 dsi->info.panel_reset_timeout_msec = 3851 dsi->info.panel_reset_timeout_msec =
3662 DEFAULT_PANEL_RESET_TIMEOUT; 3852 DEFAULT_PANEL_RESET_TIMEOUT;
3663
3664 if (!dsi->info.panel_buffer_size_byte) 3853 if (!dsi->info.panel_buffer_size_byte)
3665 dsi->info.panel_buffer_size_byte = DEFAULT_PANEL_BUFFER_BYTE; 3854 dsi->info.panel_buffer_size_byte = DEFAULT_PANEL_BUFFER_BYTE;
3666 3855
@@ -3690,16 +3879,6 @@ static int tegra_dc_dsi_cp_info(struct tegra_dc_dsi_data *dsi,
3690 /* host mode is for testing only */ 3879 /* host mode is for testing only */
3691 dsi->driven_mode = TEGRA_DSI_DRIVEN_BY_DC; 3880 dsi->driven_mode = TEGRA_DSI_DRIVEN_BY_DC;
3692 return 0; 3881 return 0;
3693
3694err_free:
3695 kfree(p_suspend_cmd);
3696err_free_p_late_resume_cmd:
3697 kfree(p_late_resume_cmd);
3698err_free_p_early_suspend_cmd:
3699 kfree(p_early_suspend_cmd);
3700err_free_init_cmd:
3701 kfree(p_init_cmd);
3702 return err;
3703} 3882}
3704 3883
3705/* returns next null enumeration from tegra_dsi_instance */ 3884/* returns next null enumeration from tegra_dsi_instance */
@@ -3723,25 +3902,21 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
3723 struct clk *dsi_clk = NULL; 3902 struct clk *dsi_clk = NULL;
3724 struct clk *dsi_fixed_clk = NULL; 3903 struct clk *dsi_fixed_clk = NULL;
3725 struct clk *dsi_lp_clk = NULL; 3904 struct clk *dsi_lp_clk = NULL;
3726 struct tegra_dsi_out *dsi_pdata;
3727 int err = 0; 3905 int err = 0;
3728 int dsi_enum = -1; 3906 int dsi_enum = -1;
3729 3907
3730 if (dc->pdata->default_out->dsi->dsi_instance)
3731 dsi_enum = 1;
3732 else
3733 dsi_enum = tegra_dsi_get_enumeration();
3734 if (dsi_enum < 0) {
3735 err = -EINVAL;
3736 dev_err(&dc->ndev->dev, "dsi: invalid enum retured\n");
3737 return err;
3738 }
3739
3740 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 3908 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
3741 if (!dsi) { 3909 if (!dsi) {
3742 dev_err(&dc->ndev->dev, "dsi: memory allocation failed\n"); 3910 dev_err(&dc->ndev->dev, "dsi: memory allocation failed\n");
3743 return -ENOMEM; 3911 return -ENOMEM;
3744 } 3912 }
3913
3914 dsi->dc = dc;
3915 err = tegra_dc_dsi_cp_info(dsi);
3916 if (err < 0)
3917 goto err_free_dsi;
3918
3919 dsi_enum = dsi->info.dsi_instance ? : tegra_dsi_get_enumeration();
3745 tegra_dsi_instance[dsi_enum] = dsi; 3920 tegra_dsi_instance[dsi_enum] = dsi;
3746 3921
3747 if (dc->out->dsi->ganged_type) { 3922 if (dc->out->dsi->ganged_type) {
@@ -3780,11 +3955,6 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
3780 goto err_release_regs; 3955 goto err_release_regs;
3781 } 3956 }
3782 3957
3783 dsi_pdata = dc->pdata->default_out->dsi;
3784 if (!dsi_pdata) {
3785 dev_err(&dc->ndev->dev, "dsi: dsi data not available\n");
3786 goto err_release_regs;
3787 }
3788 if (dsi_enum) { 3958 if (dsi_enum) {
3789 dsi_clk = clk_get(&dc->ndev->dev, "dsib"); 3959 dsi_clk = clk_get(&dc->ndev->dev, "dsib");
3790 dsi_lp_clk = clk_get(&dc->ndev->dev, "dsiblp"); 3960 dsi_lp_clk = clk_get(&dc->ndev->dev, "dsiblp");
@@ -3811,7 +3981,6 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
3811 3981
3812 mutex_init(&dsi->lock); 3982 mutex_init(&dsi->lock);
3813 dsi->controller_index = dsi_enum; 3983 dsi->controller_index = dsi_enum;
3814 dsi->dc = dc;
3815 dsi->base = base; 3984 dsi->base = base;
3816 dsi->base_res = base_res; 3985 dsi->base_res = base_res;
3817 dsi->dc_clk = dc_clk; 3986 dsi->dc_clk = dc_clk;
@@ -3819,17 +3988,11 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
3819 dsi->dsi_fixed_clk = dsi_fixed_clk; 3988 dsi->dsi_fixed_clk = dsi_fixed_clk;
3820 dsi->dsi_lp_clk = dsi_lp_clk; 3989 dsi->dsi_lp_clk = dsi_lp_clk;
3821 3990
3822 err = tegra_dc_dsi_cp_info(dsi, dsi_pdata);
3823 if (err < 0)
3824 goto err_dc_clk_put;
3825
3826 tegra_dc_set_outdata(dc, dsi); 3991 tegra_dc_set_outdata(dc, dsi);
3827 __tegra_dc_dsi_init(dc); 3992 __tegra_dc_dsi_init(dc);
3828 3993
3829 return 0; 3994 return 0;
3830 3995
3831err_dc_clk_put:
3832 clk_put(dc_clk);
3833err_dsi_clk_put: 3996err_dsi_clk_put:
3834 clk_put(dsi_clk); 3997 clk_put(dsi_clk);
3835 clk_put(dsi_fixed_clk); 3998 clk_put(dsi_fixed_clk);