2 * shmob_drm_kms.c -- SH Mobile DRM Mode Setting
4 * Copyright (C) 2012 Renesas Electronics Corporation
6 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
15 #include <drm/drm_crtc.h>
16 #include <drm/drm_crtc_helper.h>
17 #include <drm/drm_fb_cma_helper.h>
18 #include <drm/drm_gem_cma_helper.h>
19 #include <drm/drm_gem_framebuffer_helper.h>
21 #include <video/sh_mobile_meram.h>
23 #include "shmob_drm_crtc.h"
24 #include "shmob_drm_drv.h"
25 #include "shmob_drm_kms.h"
26 #include "shmob_drm_regs.h"
28 /* -----------------------------------------------------------------------------
32 static const struct shmob_drm_format_info shmob_drm_format_infos
[] = {
34 .fourcc
= DRM_FORMAT_RGB565
,
37 .lddfr
= LDDFR_PKF_RGB16
,
38 .meram
= SH_MOBILE_MERAM_PF_RGB
,
40 .fourcc
= DRM_FORMAT_RGB888
,
43 .lddfr
= LDDFR_PKF_RGB24
,
44 .meram
= SH_MOBILE_MERAM_PF_RGB
,
46 .fourcc
= DRM_FORMAT_ARGB8888
,
49 .lddfr
= LDDFR_PKF_ARGB32
,
50 .meram
= SH_MOBILE_MERAM_PF_RGB
,
52 .fourcc
= DRM_FORMAT_NV12
,
55 .lddfr
= LDDFR_CC
| LDDFR_YF_420
,
56 .meram
= SH_MOBILE_MERAM_PF_NV
,
58 .fourcc
= DRM_FORMAT_NV21
,
61 .lddfr
= LDDFR_CC
| LDDFR_YF_420
,
62 .meram
= SH_MOBILE_MERAM_PF_NV
,
64 .fourcc
= DRM_FORMAT_NV16
,
67 .lddfr
= LDDFR_CC
| LDDFR_YF_422
,
68 .meram
= SH_MOBILE_MERAM_PF_NV
,
70 .fourcc
= DRM_FORMAT_NV61
,
73 .lddfr
= LDDFR_CC
| LDDFR_YF_422
,
74 .meram
= SH_MOBILE_MERAM_PF_NV
,
76 .fourcc
= DRM_FORMAT_NV24
,
79 .lddfr
= LDDFR_CC
| LDDFR_YF_444
,
80 .meram
= SH_MOBILE_MERAM_PF_NV24
,
82 .fourcc
= DRM_FORMAT_NV42
,
85 .lddfr
= LDDFR_CC
| LDDFR_YF_444
,
86 .meram
= SH_MOBILE_MERAM_PF_NV24
,
90 const struct shmob_drm_format_info
*shmob_drm_format_info(u32 fourcc
)
94 for (i
= 0; i
< ARRAY_SIZE(shmob_drm_format_infos
); ++i
) {
95 if (shmob_drm_format_infos
[i
].fourcc
== fourcc
)
96 return &shmob_drm_format_infos
[i
];
102 /* -----------------------------------------------------------------------------
106 static struct drm_framebuffer
*
107 shmob_drm_fb_create(struct drm_device
*dev
, struct drm_file
*file_priv
,
108 const struct drm_mode_fb_cmd2
*mode_cmd
)
110 const struct shmob_drm_format_info
*format
;
112 format
= shmob_drm_format_info(mode_cmd
->pixel_format
);
113 if (format
== NULL
) {
114 dev_dbg(dev
->dev
, "unsupported pixel format %08x\n",
115 mode_cmd
->pixel_format
);
116 return ERR_PTR(-EINVAL
);
119 if (mode_cmd
->pitches
[0] & 7 || mode_cmd
->pitches
[0] >= 65536) {
120 dev_dbg(dev
->dev
, "invalid pitch value %u\n",
121 mode_cmd
->pitches
[0]);
122 return ERR_PTR(-EINVAL
);
126 unsigned int chroma_cpp
= format
->bpp
== 24 ? 2 : 1;
128 if (mode_cmd
->pitches
[1] != mode_cmd
->pitches
[0] * chroma_cpp
) {
130 "luma and chroma pitches do not match\n");
131 return ERR_PTR(-EINVAL
);
135 return drm_gem_fb_create(dev
, file_priv
, mode_cmd
);
138 static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs
= {
139 .fb_create
= shmob_drm_fb_create
,
142 int shmob_drm_modeset_init(struct shmob_drm_device
*sdev
)
144 drm_mode_config_init(sdev
->ddev
);
146 shmob_drm_crtc_create(sdev
);
147 shmob_drm_encoder_create(sdev
);
148 shmob_drm_connector_create(sdev
, &sdev
->encoder
.encoder
);
150 drm_kms_helper_poll_init(sdev
->ddev
);
152 sdev
->ddev
->mode_config
.min_width
= 0;
153 sdev
->ddev
->mode_config
.min_height
= 0;
154 sdev
->ddev
->mode_config
.max_width
= 4095;
155 sdev
->ddev
->mode_config
.max_height
= 4095;
156 sdev
->ddev
->mode_config
.funcs
= &shmob_drm_mode_config_funcs
;
158 drm_helper_disable_unused_functions(sdev
->ddev
);