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>
20 #include <video/sh_mobile_meram.h>
22 #include "shmob_drm_crtc.h"
23 #include "shmob_drm_drv.h"
24 #include "shmob_drm_kms.h"
25 #include "shmob_drm_regs.h"
27 /* -----------------------------------------------------------------------------
31 static const struct shmob_drm_format_info shmob_drm_format_infos
[] = {
33 .fourcc
= DRM_FORMAT_RGB565
,
36 .lddfr
= LDDFR_PKF_RGB16
,
37 .meram
= SH_MOBILE_MERAM_PF_RGB
,
39 .fourcc
= DRM_FORMAT_RGB888
,
42 .lddfr
= LDDFR_PKF_RGB24
,
43 .meram
= SH_MOBILE_MERAM_PF_RGB
,
45 .fourcc
= DRM_FORMAT_ARGB8888
,
48 .lddfr
= LDDFR_PKF_ARGB32
,
49 .meram
= SH_MOBILE_MERAM_PF_RGB
,
51 .fourcc
= DRM_FORMAT_NV12
,
54 .lddfr
= LDDFR_CC
| LDDFR_YF_420
,
55 .meram
= SH_MOBILE_MERAM_PF_NV
,
57 .fourcc
= DRM_FORMAT_NV21
,
60 .lddfr
= LDDFR_CC
| LDDFR_YF_420
,
61 .meram
= SH_MOBILE_MERAM_PF_NV
,
63 .fourcc
= DRM_FORMAT_NV16
,
66 .lddfr
= LDDFR_CC
| LDDFR_YF_422
,
67 .meram
= SH_MOBILE_MERAM_PF_NV
,
69 .fourcc
= DRM_FORMAT_NV61
,
72 .lddfr
= LDDFR_CC
| LDDFR_YF_422
,
73 .meram
= SH_MOBILE_MERAM_PF_NV
,
75 .fourcc
= DRM_FORMAT_NV24
,
78 .lddfr
= LDDFR_CC
| LDDFR_YF_444
,
79 .meram
= SH_MOBILE_MERAM_PF_NV24
,
81 .fourcc
= DRM_FORMAT_NV42
,
84 .lddfr
= LDDFR_CC
| LDDFR_YF_444
,
85 .meram
= SH_MOBILE_MERAM_PF_NV24
,
89 const struct shmob_drm_format_info
*shmob_drm_format_info(u32 fourcc
)
93 for (i
= 0; i
< ARRAY_SIZE(shmob_drm_format_infos
); ++i
) {
94 if (shmob_drm_format_infos
[i
].fourcc
== fourcc
)
95 return &shmob_drm_format_infos
[i
];
101 /* -----------------------------------------------------------------------------
105 static struct drm_framebuffer
*
106 shmob_drm_fb_create(struct drm_device
*dev
, struct drm_file
*file_priv
,
107 const struct drm_mode_fb_cmd2
*mode_cmd
)
109 const struct shmob_drm_format_info
*format
;
111 format
= shmob_drm_format_info(mode_cmd
->pixel_format
);
112 if (format
== NULL
) {
113 dev_dbg(dev
->dev
, "unsupported pixel format %08x\n",
114 mode_cmd
->pixel_format
);
115 return ERR_PTR(-EINVAL
);
118 if (mode_cmd
->pitches
[0] & 7 || mode_cmd
->pitches
[0] >= 65536) {
119 dev_dbg(dev
->dev
, "invalid pitch value %u\n",
120 mode_cmd
->pitches
[0]);
121 return ERR_PTR(-EINVAL
);
125 unsigned int chroma_cpp
= format
->bpp
== 24 ? 2 : 1;
127 if (mode_cmd
->pitches
[1] != mode_cmd
->pitches
[0] * chroma_cpp
) {
129 "luma and chroma pitches do not match\n");
130 return ERR_PTR(-EINVAL
);
134 return drm_fb_cma_create(dev
, file_priv
, mode_cmd
);
137 static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs
= {
138 .fb_create
= shmob_drm_fb_create
,
141 int shmob_drm_modeset_init(struct shmob_drm_device
*sdev
)
143 drm_mode_config_init(sdev
->ddev
);
145 shmob_drm_crtc_create(sdev
);
146 shmob_drm_encoder_create(sdev
);
147 shmob_drm_connector_create(sdev
, &sdev
->encoder
.encoder
);
149 drm_kms_helper_poll_init(sdev
->ddev
);
151 sdev
->ddev
->mode_config
.min_width
= 0;
152 sdev
->ddev
->mode_config
.min_height
= 0;
153 sdev
->ddev
->mode_config
.max_width
= 4095;
154 sdev
->ddev
->mode_config
.max_height
= 4095;
155 sdev
->ddev
->mode_config
.funcs
= &shmob_drm_mode_config_funcs
;
157 drm_helper_disable_unused_functions(sdev
->ddev
);