1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * MIPI Display Bus Interface (DBI) LCD controller support 4 * 5 * Copyright 2016 Noralf Trønnes 6 */ 7 8 #ifndef __LINUX_MIPI_DBI_H 9 #define __LINUX_MIPI_DBI_H 10 11 #include <linux/mutex.h> 12 13 #include <drm/drm_atomic_state_helper.h> 14 #include <drm/drm_device.h> 15 #include <drm/drm_gem_atomic_helper.h> 16 #include <drm/drm_gem_framebuffer_helper.h> 17 #include <drm/drm_probe_helper.h> 18 19 struct drm_format_conv_state; 20 struct drm_rect; 21 struct gpio_desc; 22 struct iosys_map; 23 struct regulator; 24 struct spi_device; 25 26 /** 27 * struct mipi_dbi - MIPI DBI interface 28 */ 29 struct mipi_dbi { 30 /** 31 * @cmdlock: Command lock 32 */ 33 struct mutex cmdlock; 34 35 /** 36 * @command: Bus specific callback executing commands. 37 */ 38 int (*command)(struct mipi_dbi *dbi, u8 *cmd, u8 *param, size_t num); 39 40 /** 41 * @read_commands: Array of read commands terminated by a zero entry. 42 * Reading is disabled if this is NULL. 43 */ 44 const u8 *read_commands; 45 46 /** 47 * @swap_bytes: Swap bytes in buffer before transfer 48 */ 49 bool swap_bytes; 50 51 /** 52 * @reset: Optional reset gpio 53 */ 54 struct gpio_desc *reset; 55 56 /* Type C specific */ 57 58 /** 59 * @spi: SPI device 60 */ 61 struct spi_device *spi; 62 63 /** 64 * @write_memory_bpw: Bits per word used on a MIPI_DCS_WRITE_MEMORY_START transfer 65 */ 66 unsigned int write_memory_bpw; 67 68 /** 69 * @dc: Optional D/C gpio. 70 */ 71 struct gpio_desc *dc; 72 73 /** 74 * @tx_buf9: Buffer used for Option 1 9-bit conversion 75 */ 76 void *tx_buf9; 77 78 /** 79 * @tx_buf9_len: Size of tx_buf9. 80 */ 81 size_t tx_buf9_len; 82 }; 83 84 /** 85 * struct mipi_dbi_dev - MIPI DBI device 86 */ 87 struct mipi_dbi_dev { 88 /** 89 * @drm: DRM device 90 */ 91 struct drm_device drm; 92 93 /** 94 * @mode: Fixed display mode 95 */ 96 struct drm_display_mode mode; 97 98 /** 99 * @pixel_format: Native pixel format (DRM_FORMAT\_\*) 100 */ 101 u32 pixel_format; 102 103 /** 104 * @tx_buf: Buffer used for transfer (copy clip rect area) 105 */ 106 u16 *tx_buf; 107 108 /** 109 * @rotation: initial rotation in degrees Counter Clock Wise 110 */ 111 unsigned int rotation; 112 113 /** 114 * @left_offset: Horizontal offset of the display relative to the 115 * controller's driver array 116 */ 117 unsigned int left_offset; 118 119 /** 120 * @top_offset: Vertical offset of the display relative to the 121 * controller's driver array 122 */ 123 unsigned int top_offset; 124 125 /** 126 * @backlight: backlight device (optional) 127 */ 128 struct backlight_device *backlight; 129 130 /** 131 * @regulator: power regulator (Vdd) (optional) 132 */ 133 struct regulator *regulator; 134 135 /** 136 * @io_regulator: I/O power regulator (Vddi) (optional) 137 */ 138 struct regulator *io_regulator; 139 140 /** 141 * @dbi: MIPI DBI interface 142 */ 143 struct mipi_dbi dbi; 144 145 /** 146 * @driver_private: Driver private data. 147 * Necessary for drivers with private data since devm_drm_dev_alloc() 148 * can't allocate structures that embed a structure which then again 149 * embeds drm_device. 150 */ 151 void *driver_private; 152 }; 153 154 static inline struct mipi_dbi_dev *drm_to_mipi_dbi_dev(struct drm_device *drm) 155 { 156 return container_of(drm, struct mipi_dbi_dev, drm); 157 } 158 159 int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi, 160 struct gpio_desc *dc); 161 162 int drm_mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev, const struct drm_display_mode *mode, 163 u32 format, unsigned int rotation, size_t tx_buf_size); 164 165 void mipi_dbi_hw_reset(struct mipi_dbi *dbi); 166 bool mipi_dbi_display_is_on(struct mipi_dbi *dbi); 167 int mipi_dbi_poweron_reset(struct mipi_dbi_dev *dbidev); 168 int mipi_dbi_poweron_conditional_reset(struct mipi_dbi_dev *dbidev); 169 170 u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len); 171 int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, 172 u8 bpw, const void *buf, size_t len); 173 174 int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val); 175 int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len); 176 int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data, 177 size_t len); 178 int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *fb, 179 struct drm_rect *clip, bool swap, 180 struct drm_format_conv_state *fmtcnv_state); 181 182 /** 183 * mipi_dbi_command - MIPI DCS command with optional parameter(s) 184 * @dbi: MIPI DBI structure 185 * @cmd: Command 186 * @seq: Optional parameter(s) 187 * 188 * Send MIPI DCS command to the controller. Use mipi_dbi_command_read() for 189 * get/read. 190 * 191 * Returns: 192 * Zero on success, negative error code on failure. 193 */ 194 #define mipi_dbi_command(dbi, cmd, seq...) \ 195 ({ \ 196 const u8 d[] = { seq }; \ 197 struct device *dev = &(dbi)->spi->dev; \ 198 int ret; \ 199 ret = mipi_dbi_command_stackbuf(dbi, cmd, d, ARRAY_SIZE(d)); \ 200 if (ret) \ 201 dev_err_ratelimited(dev, "error %d when sending command %#02x\n", ret, cmd); \ 202 ret; \ 203 }) 204 205 /* 206 * Plane 207 */ 208 209 #define DRM_MIPI_DBI_PLANE_FORMATS \ 210 DRM_FORMAT_RGB565, \ 211 DRM_FORMAT_XRGB8888 212 213 #define DRM_MIPI_DBI_PLANE_FORMAT_MODIFIERS \ 214 DRM_FORMAT_MOD_LINEAR, \ 215 DRM_FORMAT_MOD_INVALID 216 217 #define DRM_MIPI_DBI_PLANE_FUNCS \ 218 DRM_GEM_SHADOW_PLANE_FUNCS, \ 219 .update_plane = drm_atomic_helper_update_plane, \ 220 .disable_plane = drm_atomic_helper_disable_plane 221 222 int drm_mipi_dbi_plane_helper_atomic_check(struct drm_plane *plane, 223 struct drm_atomic_state *state); 224 void drm_mipi_dbi_plane_helper_atomic_update(struct drm_plane *plane, 225 struct drm_atomic_state *state); 226 227 #define DRM_MIPI_DBI_PLANE_HELPER_FUNCS \ 228 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, \ 229 .atomic_check = drm_mipi_dbi_plane_helper_atomic_check, \ 230 .atomic_update = drm_mipi_dbi_plane_helper_atomic_update 231 232 /* 233 * CRTC 234 */ 235 236 #define DRM_MIPI_DBI_CRTC_FUNCS \ 237 .reset = drm_atomic_helper_crtc_reset, \ 238 .set_config = drm_atomic_helper_set_config, \ 239 .page_flip = drm_atomic_helper_page_flip, \ 240 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, \ 241 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state 242 243 enum drm_mode_status drm_mipi_dbi_crtc_helper_mode_valid(struct drm_crtc *crtc, 244 const struct drm_display_mode *mode); 245 int drm_mipi_dbi_crtc_helper_atomic_check(struct drm_crtc *crtc, 246 struct drm_atomic_state *state); 247 void drm_mipi_dbi_crtc_helper_atomic_disable(struct drm_crtc *crtc, 248 struct drm_atomic_state *state); 249 250 #define DRM_MIPI_DBI_CRTC_HELPER_FUNCS \ 251 .mode_valid = drm_mipi_dbi_crtc_helper_mode_valid, \ 252 .atomic_check = drm_mipi_dbi_crtc_helper_atomic_check, \ 253 .atomic_disable = drm_mipi_dbi_crtc_helper_atomic_disable 254 255 /* 256 * Connector 257 */ 258 259 #define DRM_MIPI_DBI_CONNECTOR_FUNCS \ 260 .reset = drm_atomic_helper_connector_reset, \ 261 .fill_modes = drm_helper_probe_single_connector_modes, \ 262 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \ 263 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state 264 265 int drm_mipi_dbi_connector_helper_get_modes(struct drm_connector *connector); 266 267 #define DRM_MIPI_DBI_CONNECTOR_HELPER_FUNCS \ 268 .get_modes = drm_mipi_dbi_connector_helper_get_modes 269 270 /* 271 * Mode config 272 */ 273 274 #define DRM_MIPI_DBI_MODE_CONFIG_FUNCS \ 275 .fb_create = drm_gem_fb_create_with_dirty, \ 276 .atomic_check = drm_atomic_helper_check, \ 277 .atomic_commit = drm_atomic_helper_commit 278 279 #define DRM_MIPI_DBI_MODE_CONFIG_HELPER_FUNCS \ 280 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm 281 282 /* 283 * Debug FS 284 */ 285 286 #ifdef CONFIG_DEBUG_FS 287 void mipi_dbi_debugfs_init(struct drm_minor *minor); 288 #else 289 static inline void mipi_dbi_debugfs_init(struct drm_minor *minor) {} 290 #endif 291 292 #endif /* __LINUX_MIPI_DBI_H */ 293