Merge git://github.com/davem330/ide
[pandora-kernel.git] / drivers / staging / gma500 / mdfld_output.c
1 /*
2  * Copyright (c)  2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicensen
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  * Thomas Eaton <thomas.g.eaton@intel.com>
25  * Scott Rowe <scott.m.rowe@intel.com>
26 */
27
28 #include <linux/init.h>
29 #include "mdfld_dsi_dbi.h"
30 #include "mdfld_dsi_dpi.h"
31 #include "mdfld_dsi_output.h"
32 #include "mdfld_output.h"
33 #include "mdfld_dsi_dbi_dpu.h"
34
35 #include "displays/tpo_cmd.h"
36 #include "displays/tpo_vid.h"
37 #include "displays/tmd_cmd.h"
38 #include "displays/tmd_vid.h"
39 #include "displays/pyr_cmd.h"
40 #include "displays/pyr_vid.h"
41 /* #include "displays/hdmi.h" */
42
43 static int mdfld_dual_mipi;
44 static int mdfld_hdmi;
45 static int mdfld_dpu;
46
47 module_param(mdfld_dual_mipi, int, 0600);
48 MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration");
49 module_param(mdfld_hdmi, int, 0600);
50 MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI");
51 module_param(mdfld_dpu, int, 0600);
52 MODULE_PARM_DESC(mdfld_dpu, "Enable Medfield DPU");
53
54 /* For now a single type per device is all we cope with */
55 int mdfld_get_panel_type(struct drm_device *dev, int pipe)
56 {
57         struct drm_psb_private *dev_priv = dev->dev_private;
58         return dev_priv->panel_id;
59 }
60
61 int mdfld_panel_dpi(struct drm_device *dev)
62 {
63         struct drm_psb_private *dev_priv = dev->dev_private;
64
65         switch (dev_priv->panel_id) {
66         case TMD_VID:
67         case TPO_VID:
68         case PYR_VID:
69                 return true;
70         case TMD_CMD:
71         case TPO_CMD:
72         case PYR_CMD:
73         default:
74                 return false;
75         }
76 }
77
78 static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
79 {
80         struct panel_funcs *p_cmd_funcs;
81         struct panel_funcs *p_vid_funcs;
82
83         /* Oh boy ... FIXME */
84         p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
85         if (p_cmd_funcs == NULL)
86                 return -ENODEV;
87         p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
88         if (p_vid_funcs == NULL) {
89                 kfree(p_cmd_funcs);
90                 return -ENODEV;
91         }
92
93         switch (p_type) {
94         case TPO_CMD:
95                 tpo_cmd_init(dev, p_cmd_funcs);
96                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
97                 break;
98         case TPO_VID:
99                 tpo_vid_init(dev, p_vid_funcs);
100                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
101                 break;
102         case TMD_CMD:
103                 /*tmd_cmd_init(dev, p_cmd_funcs); */
104                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
105                 break;
106         case TMD_VID:
107                 tmd_vid_init(dev, p_vid_funcs);
108                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
109                 break;
110         case PYR_CMD:
111                 pyr_cmd_init(dev, p_cmd_funcs);
112                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
113                 break;
114         case PYR_VID:
115                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
116                 break;
117         case TPO:       /* TPO panel supports both cmd & vid interfaces */
118                 tpo_cmd_init(dev, p_cmd_funcs);
119                 tpo_vid_init(dev, p_vid_funcs);
120                 mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs,
121                                       p_vid_funcs);
122                 break;
123         case TMD:
124                 break;
125         case PYR:
126                 break;
127 #if 0
128         case HDMI:
129                 dev_dbg(dev->dev, "Initializing HDMI");
130                 mdfld_hdmi_init(dev, &dev_priv->mode_dev);
131                 break;
132 #endif
133         default:
134                 dev_err(dev->dev, "Unsupported interface %d", p_type);
135                 return -ENODEV;
136         }
137         return 0;
138 }
139
140 int mdfld_output_init(struct drm_device *dev)
141 {
142         int type;
143
144         /* MIPI panel 1 */
145         type = mdfld_get_panel_type(dev, 0);
146         dev_info(dev->dev, "panel 1: type is %d\n", type);
147         init_panel(dev, 0, type);
148
149         if (mdfld_dual_mipi) {
150                 /* MIPI panel 2 */
151                 type = mdfld_get_panel_type(dev, 2);
152                 dev_info(dev->dev, "panel 2: type is %d\n", type);
153                 init_panel(dev, 2, type);
154         }
155         if (mdfld_hdmi)
156                 /* HDMI panel */
157                 init_panel(dev, 0, HDMI);
158         return 0;
159 }
160
161 void mdfld_output_setup(struct drm_device *dev)
162 {
163         /* FIXME: this is not the right place for this stuff ! */
164         if (IS_MFLD(dev)) {
165                 if (mdfld_dpu)
166                         mdfld_dbi_dpu_init(dev);
167                 else
168                         mdfld_dbi_dsr_init(dev);
169         }
170 }