Merge remote-tracking branch 'asoc/fix/max98357a' into asoc-linus
[cascardo/linux.git] / drivers / gpu / drm / sti / sti_dvo.c
1 /*
2  * Copyright (C) STMicroelectronics SA 2014
3  * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
4  * License terms:  GNU General Public License (GPL), version 2
5  */
6
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/module.h>
10 #include <linux/of_gpio.h>
11 #include <linux/platform_device.h>
12
13 #include <drm/drmP.h>
14 #include <drm/drm_crtc_helper.h>
15 #include <drm/drm_panel.h>
16
17 #include "sti_awg_utils.h"
18 #include "sti_mixer.h"
19
20 /* DVO registers */
21 #define DVO_AWG_DIGSYNC_CTRL      0x0000
22 #define DVO_DOF_CFG               0x0004
23 #define DVO_LUT_PROG_LOW          0x0008
24 #define DVO_LUT_PROG_MID          0x000C
25 #define DVO_LUT_PROG_HIGH         0x0010
26 #define DVO_DIGSYNC_INSTR_I       0x0100
27
28 #define DVO_AWG_CTRL_EN           BIT(0)
29 #define DVO_AWG_FRAME_BASED_SYNC  BIT(2)
30
31 #define DVO_DOF_EN_LOWBYTE        BIT(0)
32 #define DVO_DOF_EN_MIDBYTE        BIT(1)
33 #define DVO_DOF_EN_HIGHBYTE       BIT(2)
34 #define DVO_DOF_EN                BIT(6)
35 #define DVO_DOF_MOD_COUNT_SHIFT   8
36
37 #define DVO_LUT_ZERO              0
38 #define DVO_LUT_Y_G               1
39 #define DVO_LUT_Y_G_DEL           2
40 #define DVO_LUT_CB_B              3
41 #define DVO_LUT_CB_B_DEL          4
42 #define DVO_LUT_CR_R              5
43 #define DVO_LUT_CR_R_DEL          6
44 #define DVO_LUT_HOLD              7
45
46 struct dvo_config {
47         u32 flags;
48         u32 lowbyte;
49         u32 midbyte;
50         u32 highbyte;
51         int (*awg_fwgen_fct)(
52                         struct awg_code_generation_params *fw_gen_params,
53                         struct awg_timing *timing);
54 };
55
56 static struct dvo_config rgb_24bit_de_cfg = {
57         .flags         = (0L << DVO_DOF_MOD_COUNT_SHIFT),
58         .lowbyte       = DVO_LUT_CR_R,
59         .midbyte       = DVO_LUT_Y_G,
60         .highbyte      = DVO_LUT_CB_B,
61         .awg_fwgen_fct = sti_awg_generate_code_data_enable_mode,
62 };
63
64 /**
65  * STI digital video output structure
66  *
67  * @dev: driver device
68  * @drm_dev: pointer to drm device
69  * @mode: current display mode selected
70  * @regs: dvo registers
71  * @clk_pix: pixel clock for dvo
72  * @clk: clock for dvo
73  * @clk_main_parent: dvo parent clock if main path used
74  * @clk_aux_parent: dvo parent clock if aux path used
75  * @panel_node: panel node reference from device tree
76  * @panel: reference to the panel connected to the dvo
77  * @enabled: true if dvo is enabled else false
78  * @encoder: drm_encoder it is bound
79  */
80 struct sti_dvo {
81         struct device dev;
82         struct drm_device *drm_dev;
83         struct drm_display_mode mode;
84         void __iomem *regs;
85         struct clk *clk_pix;
86         struct clk *clk;
87         struct clk *clk_main_parent;
88         struct clk *clk_aux_parent;
89         struct device_node *panel_node;
90         struct drm_panel *panel;
91         struct dvo_config *config;
92         bool enabled;
93         struct drm_encoder *encoder;
94         struct drm_bridge *bridge;
95 };
96
97 struct sti_dvo_connector {
98         struct drm_connector drm_connector;
99         struct drm_encoder *encoder;
100         struct sti_dvo *dvo;
101 };
102
103 #define to_sti_dvo_connector(x) \
104         container_of(x, struct sti_dvo_connector, drm_connector)
105
106 #define BLANKING_LEVEL 16
107 int dvo_awg_generate_code(struct sti_dvo *dvo, u8 *ram_size, u32 *ram_code)
108 {
109         struct drm_display_mode *mode = &dvo->mode;
110         struct dvo_config *config = dvo->config;
111         struct awg_code_generation_params fw_gen_params;
112         struct awg_timing timing;
113
114         fw_gen_params.ram_code = ram_code;
115         fw_gen_params.instruction_offset = 0;
116
117         timing.total_lines = mode->vtotal;
118         timing.active_lines = mode->vdisplay;
119         timing.blanking_lines = mode->vsync_start - mode->vdisplay;
120         timing.trailing_lines = mode->vtotal - mode->vsync_start;
121         timing.total_pixels = mode->htotal;
122         timing.active_pixels = mode->hdisplay;
123         timing.blanking_pixels = mode->hsync_start - mode->hdisplay;
124         timing.trailing_pixels = mode->htotal - mode->hsync_start;
125         timing.blanking_level = BLANKING_LEVEL;
126
127         if (config->awg_fwgen_fct(&fw_gen_params, &timing)) {
128                 DRM_ERROR("AWG firmware not properly generated\n");
129                 return -EINVAL;
130         }
131
132         *ram_size = fw_gen_params.instruction_offset;
133
134         return 0;
135 }
136
137 /* Configure AWG, writing instructions
138  *
139  * @dvo: pointer to DVO structure
140  * @awg_ram_code: pointer to AWG instructions table
141  * @nb: nb of AWG instructions
142  */
143 static void dvo_awg_configure(struct sti_dvo *dvo, u32 *awg_ram_code, int nb)
144 {
145         int i;
146
147         DRM_DEBUG_DRIVER("\n");
148
149         for (i = 0; i < nb; i++)
150                 writel(awg_ram_code[i],
151                        dvo->regs + DVO_DIGSYNC_INSTR_I + i * 4);
152         for (i = nb; i < AWG_MAX_INST; i++)
153                 writel(0, dvo->regs + DVO_DIGSYNC_INSTR_I + i * 4);
154
155         writel(DVO_AWG_CTRL_EN, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
156 }
157
158 static void sti_dvo_disable(struct drm_bridge *bridge)
159 {
160         struct sti_dvo *dvo = bridge->driver_private;
161
162         if (!dvo->enabled)
163                 return;
164
165         DRM_DEBUG_DRIVER("\n");
166
167         if (dvo->config->awg_fwgen_fct)
168                 writel(0x00000000, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
169
170         writel(0x00000000, dvo->regs + DVO_DOF_CFG);
171
172         if (dvo->panel)
173                 dvo->panel->funcs->disable(dvo->panel);
174
175         /* Disable/unprepare dvo clock */
176         clk_disable_unprepare(dvo->clk_pix);
177         clk_disable_unprepare(dvo->clk);
178
179         dvo->enabled = false;
180 }
181
182 static void sti_dvo_pre_enable(struct drm_bridge *bridge)
183 {
184         struct sti_dvo *dvo = bridge->driver_private;
185         struct dvo_config *config = dvo->config;
186         u32 val;
187
188         DRM_DEBUG_DRIVER("\n");
189
190         if (dvo->enabled)
191                 return;
192
193         /* Make sure DVO is disabled */
194         writel(0x00000000, dvo->regs + DVO_DOF_CFG);
195         writel(0x00000000, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
196
197         if (config->awg_fwgen_fct) {
198                 u8 nb_instr;
199                 u32 awg_ram_code[AWG_MAX_INST];
200                 /* Configure AWG */
201                 if (!dvo_awg_generate_code(dvo, &nb_instr, awg_ram_code))
202                         dvo_awg_configure(dvo, awg_ram_code, nb_instr);
203                 else
204                         return;
205         }
206
207         /* Prepare/enable clocks */
208         if (clk_prepare_enable(dvo->clk_pix))
209                 DRM_ERROR("Failed to prepare/enable dvo_pix clk\n");
210         if (clk_prepare_enable(dvo->clk))
211                 DRM_ERROR("Failed to prepare/enable dvo clk\n");
212
213         if (dvo->panel)
214                 dvo->panel->funcs->enable(dvo->panel);
215
216         /* Set LUT */
217         writel(config->lowbyte,  dvo->regs + DVO_LUT_PROG_LOW);
218         writel(config->midbyte,  dvo->regs + DVO_LUT_PROG_MID);
219         writel(config->highbyte, dvo->regs + DVO_LUT_PROG_HIGH);
220
221         /* Digital output formatter config */
222         val = (config->flags | DVO_DOF_EN);
223         writel(val, dvo->regs + DVO_DOF_CFG);
224
225         dvo->enabled = true;
226 }
227
228 static void sti_dvo_set_mode(struct drm_bridge *bridge,
229                              struct drm_display_mode *mode,
230                              struct drm_display_mode *adjusted_mode)
231 {
232         struct sti_dvo *dvo = bridge->driver_private;
233         struct sti_mixer *mixer = to_sti_mixer(dvo->encoder->crtc);
234         int rate = mode->clock * 1000;
235         struct clk *clkp;
236         int ret;
237
238         DRM_DEBUG_DRIVER("\n");
239
240         memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));
241
242         /* According to the path used (main or aux), the dvo clocks should
243          * have a different parent clock. */
244         if (mixer->id == STI_MIXER_MAIN)
245                 clkp = dvo->clk_main_parent;
246         else
247                 clkp = dvo->clk_aux_parent;
248
249         if (clkp) {
250                 clk_set_parent(dvo->clk_pix, clkp);
251                 clk_set_parent(dvo->clk, clkp);
252         }
253
254         /* DVO clocks = compositor clock */
255         ret = clk_set_rate(dvo->clk_pix, rate);
256         if (ret < 0) {
257                 DRM_ERROR("Cannot set rate (%dHz) for dvo_pix clk\n", rate);
258                 return;
259         }
260
261         ret = clk_set_rate(dvo->clk, rate);
262         if (ret < 0) {
263                 DRM_ERROR("Cannot set rate (%dHz) for dvo clk\n", rate);
264                 return;
265         }
266
267         /* For now, we only support 24bit data enable (DE) synchro format */
268         dvo->config = &rgb_24bit_de_cfg;
269 }
270
271 static void sti_dvo_bridge_nope(struct drm_bridge *bridge)
272 {
273         /* do nothing */
274 }
275
276 static const struct drm_bridge_funcs sti_dvo_bridge_funcs = {
277         .pre_enable = sti_dvo_pre_enable,
278         .enable = sti_dvo_bridge_nope,
279         .disable = sti_dvo_disable,
280         .post_disable = sti_dvo_bridge_nope,
281         .mode_set = sti_dvo_set_mode,
282 };
283
284 static int sti_dvo_connector_get_modes(struct drm_connector *connector)
285 {
286         struct sti_dvo_connector *dvo_connector
287                 = to_sti_dvo_connector(connector);
288         struct sti_dvo *dvo = dvo_connector->dvo;
289
290         if (dvo->panel)
291                 return dvo->panel->funcs->get_modes(dvo->panel);
292
293         return 0;
294 }
295
296 #define CLK_TOLERANCE_HZ 50
297
298 static int sti_dvo_connector_mode_valid(struct drm_connector *connector,
299                                         struct drm_display_mode *mode)
300 {
301         int target = mode->clock * 1000;
302         int target_min = target - CLK_TOLERANCE_HZ;
303         int target_max = target + CLK_TOLERANCE_HZ;
304         int result;
305         struct sti_dvo_connector *dvo_connector
306                 = to_sti_dvo_connector(connector);
307         struct sti_dvo *dvo = dvo_connector->dvo;
308
309         result = clk_round_rate(dvo->clk_pix, target);
310
311         DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
312                          target, result);
313
314         if ((result < target_min) || (result > target_max)) {
315                 DRM_DEBUG_DRIVER("dvo pixclk=%d not supported\n", target);
316                 return MODE_BAD;
317         }
318
319         return MODE_OK;
320 }
321
322 struct drm_encoder *sti_dvo_best_encoder(struct drm_connector *connector)
323 {
324         struct sti_dvo_connector *dvo_connector
325                 = to_sti_dvo_connector(connector);
326
327         /* Best encoder is the one associated during connector creation */
328         return dvo_connector->encoder;
329 }
330
331 static struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
332         .get_modes = sti_dvo_connector_get_modes,
333         .mode_valid = sti_dvo_connector_mode_valid,
334         .best_encoder = sti_dvo_best_encoder,
335 };
336
337 static enum drm_connector_status
338 sti_dvo_connector_detect(struct drm_connector *connector, bool force)
339 {
340         struct sti_dvo_connector *dvo_connector
341                 = to_sti_dvo_connector(connector);
342         struct sti_dvo *dvo = dvo_connector->dvo;
343
344         DRM_DEBUG_DRIVER("\n");
345
346         if (!dvo->panel)
347                 dvo->panel = of_drm_find_panel(dvo->panel_node);
348
349         if (dvo->panel)
350                 if (!drm_panel_attach(dvo->panel, connector))
351                         return connector_status_connected;
352
353         return connector_status_disconnected;
354 }
355
356 static void sti_dvo_connector_destroy(struct drm_connector *connector)
357 {
358         struct sti_dvo_connector *dvo_connector
359                 = to_sti_dvo_connector(connector);
360
361         drm_connector_unregister(connector);
362         drm_connector_cleanup(connector);
363         kfree(dvo_connector);
364 }
365
366 static struct drm_connector_funcs sti_dvo_connector_funcs = {
367         .dpms = drm_helper_connector_dpms,
368         .fill_modes = drm_helper_probe_single_connector_modes,
369         .detect = sti_dvo_connector_detect,
370         .destroy = sti_dvo_connector_destroy,
371 };
372
373 static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev)
374 {
375         struct drm_encoder *encoder;
376
377         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
378                 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
379                         return encoder;
380         }
381
382         return NULL;
383 }
384
385 static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
386 {
387         struct sti_dvo *dvo = dev_get_drvdata(dev);
388         struct drm_device *drm_dev = data;
389         struct drm_encoder *encoder;
390         struct sti_dvo_connector *connector;
391         struct drm_connector *drm_connector;
392         struct drm_bridge *bridge;
393         int err;
394
395         /* Set the drm device handle */
396         dvo->drm_dev = drm_dev;
397
398         encoder = sti_dvo_find_encoder(drm_dev);
399         if (!encoder)
400                 return -ENOMEM;
401
402         connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
403         if (!connector)
404                 return -ENOMEM;
405
406         connector->dvo = dvo;
407
408         bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
409         if (!bridge)
410                 return -ENOMEM;
411
412         bridge->driver_private = dvo;
413         bridge->funcs = &sti_dvo_bridge_funcs;
414         bridge->of_node = dvo->dev.of_node;
415         err = drm_bridge_add(bridge);
416         if (err) {
417                 DRM_ERROR("Failed to add bridge\n");
418                 return err;
419         }
420
421         err = drm_bridge_attach(drm_dev, bridge);
422         if (err) {
423                 DRM_ERROR("Failed to attach bridge\n");
424                 return err;
425         }
426
427         dvo->bridge = bridge;
428         encoder->bridge = bridge;
429         connector->encoder = encoder;
430         dvo->encoder = encoder;
431
432         drm_connector = (struct drm_connector *)connector;
433
434         drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
435
436         drm_connector_init(drm_dev, drm_connector,
437                            &sti_dvo_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
438         drm_connector_helper_add(drm_connector,
439                                  &sti_dvo_connector_helper_funcs);
440
441         err = drm_connector_register(drm_connector);
442         if (err)
443                 goto err_connector;
444
445         err = drm_mode_connector_attach_encoder(drm_connector, encoder);
446         if (err) {
447                 DRM_ERROR("Failed to attach a connector to a encoder\n");
448                 goto err_sysfs;
449         }
450
451         return 0;
452
453 err_sysfs:
454         drm_connector_unregister(drm_connector);
455 err_connector:
456         drm_bridge_remove(bridge);
457         drm_connector_cleanup(drm_connector);
458         return -EINVAL;
459 }
460
461 static void sti_dvo_unbind(struct device *dev,
462                            struct device *master, void *data)
463 {
464         struct sti_dvo *dvo = dev_get_drvdata(dev);
465
466         drm_bridge_remove(dvo->bridge);
467 }
468
469 static const struct component_ops sti_dvo_ops = {
470         .bind = sti_dvo_bind,
471         .unbind = sti_dvo_unbind,
472 };
473
474 static int sti_dvo_probe(struct platform_device *pdev)
475 {
476         struct device *dev = &pdev->dev;
477         struct sti_dvo *dvo;
478         struct resource *res;
479         struct device_node *np = dev->of_node;
480
481         DRM_INFO("%s\n", __func__);
482
483         dvo = devm_kzalloc(dev, sizeof(*dvo), GFP_KERNEL);
484         if (!dvo) {
485                 DRM_ERROR("Failed to allocate memory for DVO\n");
486                 return -ENOMEM;
487         }
488
489         dvo->dev = pdev->dev;
490
491         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvo-reg");
492         if (!res) {
493                 DRM_ERROR("Invalid dvo resource\n");
494                 return -ENOMEM;
495         }
496         dvo->regs = devm_ioremap_nocache(dev, res->start,
497                         resource_size(res));
498         if (IS_ERR(dvo->regs))
499                 return PTR_ERR(dvo->regs);
500
501         dvo->clk_pix = devm_clk_get(dev, "dvo_pix");
502         if (IS_ERR(dvo->clk_pix)) {
503                 DRM_ERROR("Cannot get dvo_pix clock\n");
504                 return PTR_ERR(dvo->clk_pix);
505         }
506
507         dvo->clk = devm_clk_get(dev, "dvo");
508         if (IS_ERR(dvo->clk)) {
509                 DRM_ERROR("Cannot get dvo clock\n");
510                 return PTR_ERR(dvo->clk);
511         }
512
513         dvo->clk_main_parent = devm_clk_get(dev, "main_parent");
514         if (IS_ERR(dvo->clk_main_parent)) {
515                 DRM_DEBUG_DRIVER("Cannot get main_parent clock\n");
516                 dvo->clk_main_parent = NULL;
517         }
518
519         dvo->clk_aux_parent = devm_clk_get(dev, "aux_parent");
520         if (IS_ERR(dvo->clk_aux_parent)) {
521                 DRM_DEBUG_DRIVER("Cannot get aux_parent clock\n");
522                 dvo->clk_aux_parent = NULL;
523         }
524
525         dvo->panel_node = of_parse_phandle(np, "sti,panel", 0);
526         if (!dvo->panel_node)
527                 DRM_ERROR("No panel associated to the dvo output\n");
528
529         platform_set_drvdata(pdev, dvo);
530
531         return component_add(&pdev->dev, &sti_dvo_ops);
532 }
533
534 static int sti_dvo_remove(struct platform_device *pdev)
535 {
536         component_del(&pdev->dev, &sti_dvo_ops);
537         return 0;
538 }
539
540 static struct of_device_id dvo_of_match[] = {
541         { .compatible = "st,stih407-dvo", },
542         { /* end node */ }
543 };
544 MODULE_DEVICE_TABLE(of, dvo_of_match);
545
546 struct platform_driver sti_dvo_driver = {
547         .driver = {
548                 .name = "sti-dvo",
549                 .owner = THIS_MODULE,
550                 .of_match_table = dvo_of_match,
551         },
552         .probe = sti_dvo_probe,
553         .remove = sti_dvo_remove,
554 };
555
556 module_platform_driver(sti_dvo_driver);
557
558 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
559 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
560 MODULE_LICENSE("GPL");