1/* 2 * linux/drivers/video/omap2/dss/dss_features.c 3 * 4 * Copyright (C) 2010 Texas Instruments 5 * Author: Archit Taneja <archit@ti.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published by 9 * the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20#include <linux/kernel.h> 21#include <linux/module.h> 22#include <linux/types.h> 23#include <linux/err.h> 24#include <linux/slab.h> 25 26#include <video/omapdss.h> 27 28#include "dss.h" 29#include "dss_features.h" 30 31/* Defines a generic omap register field */ 32struct dss_reg_field { 33 u8 start, end; 34}; 35 36struct dss_param_range { 37 int min, max; 38}; 39 40struct omap_dss_features { 41 const struct dss_reg_field *reg_fields; 42 const int num_reg_fields; 43 44 const enum dss_feat_id *features; 45 const int num_features; 46 47 const int num_mgrs; 48 const int num_ovls; 49 const int num_wbs; 50 const enum omap_display_type *supported_displays; 51 const enum omap_dss_output_id *supported_outputs; 52 const enum omap_color_mode *supported_color_modes; 53 const enum omap_overlay_caps *overlay_caps; 54 const char * const *clksrc_names; 55 const struct dss_param_range *dss_params; 56 57 const enum omap_dss_rotation_type supported_rotation_types; 58 59 const u32 buffer_size_unit; 60 const u32 burst_size_unit; 61}; 62 63/* This struct is assigned to one of the below during initialization */ 64static const struct omap_dss_features *omap_current_dss_features; 65 66static const struct dss_reg_field omap2_dss_reg_fields[] = { 67 [FEAT_REG_FIRHINC] = { 11, 0 }, 68 [FEAT_REG_FIRVINC] = { 27, 16 }, 69 [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 }, 70 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 }, 71 [FEAT_REG_FIFOSIZE] = { 8, 0 }, 72 [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, 73 [FEAT_REG_VERTICALACCU] = { 25, 16 }, 74 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, 75}; 76 77static const struct dss_reg_field omap3_dss_reg_fields[] = { 78 [FEAT_REG_FIRHINC] = { 12, 0 }, 79 [FEAT_REG_FIRVINC] = { 28, 16 }, 80 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 }, 81 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 }, 82 [FEAT_REG_FIFOSIZE] = { 10, 0 }, 83 [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, 84 [FEAT_REG_VERTICALACCU] = { 25, 16 }, 85 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, 86}; 87 88static const struct dss_reg_field am43xx_dss_reg_fields[] = { 89 [FEAT_REG_FIRHINC] = { 12, 0 }, 90 [FEAT_REG_FIRVINC] = { 28, 16 }, 91 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 }, 92 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 }, 93 [FEAT_REG_FIFOSIZE] = { 10, 0 }, 94 [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, 95 [FEAT_REG_VERTICALACCU] = { 25, 16 }, 96 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, 97}; 98 99static const struct dss_reg_field omap4_dss_reg_fields[] = { 100 [FEAT_REG_FIRHINC] = { 12, 0 }, 101 [FEAT_REG_FIRVINC] = { 28, 16 }, 102 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, 103 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, 104 [FEAT_REG_FIFOSIZE] = { 15, 0 }, 105 [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, 106 [FEAT_REG_VERTICALACCU] = { 26, 16 }, 107 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 }, 108}; 109 110static const struct dss_reg_field omap5_dss_reg_fields[] = { 111 [FEAT_REG_FIRHINC] = { 12, 0 }, 112 [FEAT_REG_FIRVINC] = { 28, 16 }, 113 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, 114 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, 115 [FEAT_REG_FIFOSIZE] = { 15, 0 }, 116 [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, 117 [FEAT_REG_VERTICALACCU] = { 26, 16 }, 118 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 }, 119}; 120 121static const enum omap_display_type omap2_dss_supported_displays[] = { 122 /* OMAP_DSS_CHANNEL_LCD */ 123 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, 124 125 /* OMAP_DSS_CHANNEL_DIGIT */ 126 OMAP_DISPLAY_TYPE_VENC, 127}; 128 129static const enum omap_display_type omap3430_dss_supported_displays[] = { 130 /* OMAP_DSS_CHANNEL_LCD */ 131 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 132 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 133 134 /* OMAP_DSS_CHANNEL_DIGIT */ 135 OMAP_DISPLAY_TYPE_VENC, 136}; 137 138static const enum omap_display_type omap3630_dss_supported_displays[] = { 139 /* OMAP_DSS_CHANNEL_LCD */ 140 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 141 OMAP_DISPLAY_TYPE_DSI, 142 143 /* OMAP_DSS_CHANNEL_DIGIT */ 144 OMAP_DISPLAY_TYPE_VENC, 145}; 146 147static const enum omap_display_type am43xx_dss_supported_displays[] = { 148 /* OMAP_DSS_CHANNEL_LCD */ 149 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, 150}; 151 152static const enum omap_display_type omap4_dss_supported_displays[] = { 153 /* OMAP_DSS_CHANNEL_LCD */ 154 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, 155 156 /* OMAP_DSS_CHANNEL_DIGIT */ 157 OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI, 158 159 /* OMAP_DSS_CHANNEL_LCD2 */ 160 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 161 OMAP_DISPLAY_TYPE_DSI, 162}; 163 164static const enum omap_display_type omap5_dss_supported_displays[] = { 165 /* OMAP_DSS_CHANNEL_LCD */ 166 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 167 OMAP_DISPLAY_TYPE_DSI, 168 169 /* OMAP_DSS_CHANNEL_DIGIT */ 170 OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI, 171 172 /* OMAP_DSS_CHANNEL_LCD2 */ 173 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 174 OMAP_DISPLAY_TYPE_DSI, 175}; 176 177static const enum omap_dss_output_id omap2_dss_supported_outputs[] = { 178 /* OMAP_DSS_CHANNEL_LCD */ 179 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, 180 181 /* OMAP_DSS_CHANNEL_DIGIT */ 182 OMAP_DSS_OUTPUT_VENC, 183}; 184 185static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = { 186 /* OMAP_DSS_CHANNEL_LCD */ 187 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 188 OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1, 189 190 /* OMAP_DSS_CHANNEL_DIGIT */ 191 OMAP_DSS_OUTPUT_VENC, 192}; 193 194static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = { 195 /* OMAP_DSS_CHANNEL_LCD */ 196 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 197 OMAP_DSS_OUTPUT_DSI1, 198 199 /* OMAP_DSS_CHANNEL_DIGIT */ 200 OMAP_DSS_OUTPUT_VENC, 201}; 202 203static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = { 204 /* OMAP_DSS_CHANNEL_LCD */ 205 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, 206}; 207 208static const enum omap_dss_output_id omap4_dss_supported_outputs[] = { 209 /* OMAP_DSS_CHANNEL_LCD */ 210 OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1, 211 212 /* OMAP_DSS_CHANNEL_DIGIT */ 213 OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI, 214 215 /* OMAP_DSS_CHANNEL_LCD2 */ 216 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 217 OMAP_DSS_OUTPUT_DSI2, 218}; 219 220static const enum omap_dss_output_id omap5_dss_supported_outputs[] = { 221 /* OMAP_DSS_CHANNEL_LCD */ 222 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 223 OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2, 224 225 /* OMAP_DSS_CHANNEL_DIGIT */ 226 OMAP_DSS_OUTPUT_HDMI, 227 228 /* OMAP_DSS_CHANNEL_LCD2 */ 229 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 230 OMAP_DSS_OUTPUT_DSI1, 231 232 /* OMAP_DSS_CHANNEL_LCD3 */ 233 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 234 OMAP_DSS_OUTPUT_DSI2, 235}; 236 237static const enum omap_color_mode omap2_dss_supported_color_modes[] = { 238 /* OMAP_DSS_GFX */ 239 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | 240 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 | 241 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 | 242 OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P, 243 244 /* OMAP_DSS_VIDEO1 */ 245 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | 246 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 | 247 OMAP_DSS_COLOR_UYVY, 248 249 /* OMAP_DSS_VIDEO2 */ 250 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | 251 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 | 252 OMAP_DSS_COLOR_UYVY, 253}; 254 255static const enum omap_color_mode omap3_dss_supported_color_modes[] = { 256 /* OMAP_DSS_GFX */ 257 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | 258 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 | 259 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 | 260 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | 261 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 | 262 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 263 264 /* OMAP_DSS_VIDEO1 */ 265 OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P | 266 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 | 267 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY, 268 269 /* OMAP_DSS_VIDEO2 */ 270 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 | 271 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | 272 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 | 273 OMAP_DSS_COLOR_UYVY | OMAP_DSS_COLOR_ARGB32 | 274 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 275}; 276 277static const enum omap_color_mode omap4_dss_supported_color_modes[] = { 278 /* OMAP_DSS_GFX */ 279 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | 280 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 | 281 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 | 282 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | 283 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 | 284 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 | 285 OMAP_DSS_COLOR_ARGB16_1555 | OMAP_DSS_COLOR_RGBX16 | 286 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_XRGB16_1555, 287 288 /* OMAP_DSS_VIDEO1 */ 289 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | 290 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | 291 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | 292 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | 293 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | 294 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | 295 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | 296 OMAP_DSS_COLOR_RGBX32, 297 298 /* OMAP_DSS_VIDEO2 */ 299 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | 300 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | 301 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | 302 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | 303 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | 304 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | 305 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | 306 OMAP_DSS_COLOR_RGBX32, 307 308 /* OMAP_DSS_VIDEO3 */ 309 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | 310 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | 311 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | 312 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | 313 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | 314 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | 315 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | 316 OMAP_DSS_COLOR_RGBX32, 317 318 /* OMAP_DSS_WB */ 319 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | 320 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | 321 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | 322 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | 323 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | 324 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | 325 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | 326 OMAP_DSS_COLOR_RGBX32, 327}; 328 329static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { 330 /* OMAP_DSS_GFX */ 331 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 332 333 /* OMAP_DSS_VIDEO1 */ 334 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | 335 OMAP_DSS_OVL_CAP_REPLICATION, 336 337 /* OMAP_DSS_VIDEO2 */ 338 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | 339 OMAP_DSS_OVL_CAP_REPLICATION, 340}; 341 342static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = { 343 /* OMAP_DSS_GFX */ 344 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS | 345 OMAP_DSS_OVL_CAP_REPLICATION, 346 347 /* OMAP_DSS_VIDEO1 */ 348 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | 349 OMAP_DSS_OVL_CAP_REPLICATION, 350 351 /* OMAP_DSS_VIDEO2 */ 352 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | 353 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 354}; 355 356static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = { 357 /* OMAP_DSS_GFX */ 358 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | 359 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 360 361 /* OMAP_DSS_VIDEO1 */ 362 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | 363 OMAP_DSS_OVL_CAP_REPLICATION, 364 365 /* OMAP_DSS_VIDEO2 */ 366 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | 367 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS | 368 OMAP_DSS_OVL_CAP_REPLICATION, 369}; 370 371static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { 372 /* OMAP_DSS_GFX */ 373 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | 374 OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS | 375 OMAP_DSS_OVL_CAP_REPLICATION, 376 377 /* OMAP_DSS_VIDEO1 */ 378 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | 379 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | 380 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 381 382 /* OMAP_DSS_VIDEO2 */ 383 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | 384 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | 385 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 386 387 /* OMAP_DSS_VIDEO3 */ 388 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | 389 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | 390 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 391}; 392 393static const char * const omap2_dss_clk_source_names[] = { 394 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A", 395 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A", 396 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK1", 397}; 398 399static const char * const omap3_dss_clk_source_names[] = { 400 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK", 401 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK", 402 [OMAP_DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK", 403}; 404 405static const char * const omap4_dss_clk_source_names[] = { 406 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1", 407 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2", 408 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK", 409 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1", 410 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", 411}; 412 413static const char * const omap5_dss_clk_source_names[] = { 414 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1", 415 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2", 416 [OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK", 417 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1", 418 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2", 419}; 420 421static const struct dss_param_range omap2_dss_param_range[] = { 422 [FEAT_PARAM_DSS_FCK] = { 0, 133000000 }, 423 [FEAT_PARAM_DSS_PCD] = { 2, 255 }, 424 [FEAT_PARAM_DOWNSCALE] = { 1, 2 }, 425 /* 426 * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC 427 * scaler cannot scale a image with width more than 768. 428 */ 429 [FEAT_PARAM_LINEWIDTH] = { 1, 768 }, 430}; 431 432static const struct dss_param_range omap3_dss_param_range[] = { 433 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, 434 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 435 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, 436 [FEAT_PARAM_DSI_FCK] = { 0, 173000000 }, 437 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 438 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, 439}; 440 441static const struct dss_param_range am43xx_dss_param_range[] = { 442 [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, 443 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 444 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 445 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, 446}; 447 448static const struct dss_param_range omap4_dss_param_range[] = { 449 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, 450 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 451 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 452 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, 453 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 454 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 455}; 456 457static const struct dss_param_range omap5_dss_param_range[] = { 458 [FEAT_PARAM_DSS_FCK] = { 0, 209250000 }, 459 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 460 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 461 [FEAT_PARAM_DSI_FCK] = { 0, 209250000 }, 462 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 463 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 464}; 465 466static const enum dss_feat_id omap2_dss_feat_list[] = { 467 FEAT_LCDENABLEPOL, 468 FEAT_LCDENABLESIGNAL, 469 FEAT_PCKFREEENABLE, 470 FEAT_FUNCGATED, 471 FEAT_ROWREPEATENABLE, 472 FEAT_RESIZECONF, 473}; 474 475static const enum dss_feat_id omap3430_dss_feat_list[] = { 476 FEAT_LCDENABLEPOL, 477 FEAT_LCDENABLESIGNAL, 478 FEAT_PCKFREEENABLE, 479 FEAT_FUNCGATED, 480 FEAT_LINEBUFFERSPLIT, 481 FEAT_ROWREPEATENABLE, 482 FEAT_RESIZECONF, 483 FEAT_DSI_REVERSE_TXCLKESC, 484 FEAT_VENC_REQUIRES_TV_DAC_CLK, 485 FEAT_CPR, 486 FEAT_PRELOAD, 487 FEAT_FIR_COEF_V, 488 FEAT_ALPHA_FIXED_ZORDER, 489 FEAT_FIFO_MERGE, 490 FEAT_OMAP3_DSI_FIFO_BUG, 491 FEAT_DPI_USES_VDDS_DSI, 492}; 493 494static const enum dss_feat_id am35xx_dss_feat_list[] = { 495 FEAT_LCDENABLEPOL, 496 FEAT_LCDENABLESIGNAL, 497 FEAT_PCKFREEENABLE, 498 FEAT_FUNCGATED, 499 FEAT_LINEBUFFERSPLIT, 500 FEAT_ROWREPEATENABLE, 501 FEAT_RESIZECONF, 502 FEAT_DSI_REVERSE_TXCLKESC, 503 FEAT_VENC_REQUIRES_TV_DAC_CLK, 504 FEAT_CPR, 505 FEAT_PRELOAD, 506 FEAT_FIR_COEF_V, 507 FEAT_ALPHA_FIXED_ZORDER, 508 FEAT_FIFO_MERGE, 509 FEAT_OMAP3_DSI_FIFO_BUG, 510}; 511 512static const enum dss_feat_id am43xx_dss_feat_list[] = { 513 FEAT_LCDENABLEPOL, 514 FEAT_LCDENABLESIGNAL, 515 FEAT_PCKFREEENABLE, 516 FEAT_FUNCGATED, 517 FEAT_LINEBUFFERSPLIT, 518 FEAT_ROWREPEATENABLE, 519 FEAT_RESIZECONF, 520 FEAT_CPR, 521 FEAT_PRELOAD, 522 FEAT_FIR_COEF_V, 523 FEAT_ALPHA_FIXED_ZORDER, 524 FEAT_FIFO_MERGE, 525}; 526 527static const enum dss_feat_id omap3630_dss_feat_list[] = { 528 FEAT_LCDENABLEPOL, 529 FEAT_LCDENABLESIGNAL, 530 FEAT_PCKFREEENABLE, 531 FEAT_FUNCGATED, 532 FEAT_LINEBUFFERSPLIT, 533 FEAT_ROWREPEATENABLE, 534 FEAT_RESIZECONF, 535 FEAT_DSI_PLL_PWR_BUG, 536 FEAT_CPR, 537 FEAT_PRELOAD, 538 FEAT_FIR_COEF_V, 539 FEAT_ALPHA_FIXED_ZORDER, 540 FEAT_FIFO_MERGE, 541 FEAT_OMAP3_DSI_FIFO_BUG, 542 FEAT_DPI_USES_VDDS_DSI, 543}; 544 545static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = { 546 FEAT_MGR_LCD2, 547 FEAT_CORE_CLK_DIV, 548 FEAT_LCD_CLK_SRC, 549 FEAT_DSI_DCS_CMD_CONFIG_VC, 550 FEAT_DSI_VC_OCP_WIDTH, 551 FEAT_DSI_GNQ, 552 FEAT_HANDLE_UV_SEPARATE, 553 FEAT_ATTR2, 554 FEAT_CPR, 555 FEAT_PRELOAD, 556 FEAT_FIR_COEF_V, 557 FEAT_ALPHA_FREE_ZORDER, 558 FEAT_FIFO_MERGE, 559 FEAT_BURST_2D, 560}; 561 562static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { 563 FEAT_MGR_LCD2, 564 FEAT_CORE_CLK_DIV, 565 FEAT_LCD_CLK_SRC, 566 FEAT_DSI_DCS_CMD_CONFIG_VC, 567 FEAT_DSI_VC_OCP_WIDTH, 568 FEAT_DSI_GNQ, 569 FEAT_HDMI_CTS_SWMODE, 570 FEAT_HANDLE_UV_SEPARATE, 571 FEAT_ATTR2, 572 FEAT_CPR, 573 FEAT_PRELOAD, 574 FEAT_FIR_COEF_V, 575 FEAT_ALPHA_FREE_ZORDER, 576 FEAT_FIFO_MERGE, 577 FEAT_BURST_2D, 578}; 579 580static const enum dss_feat_id omap4_dss_feat_list[] = { 581 FEAT_MGR_LCD2, 582 FEAT_CORE_CLK_DIV, 583 FEAT_LCD_CLK_SRC, 584 FEAT_DSI_DCS_CMD_CONFIG_VC, 585 FEAT_DSI_VC_OCP_WIDTH, 586 FEAT_DSI_GNQ, 587 FEAT_HDMI_CTS_SWMODE, 588 FEAT_HDMI_AUDIO_USE_MCLK, 589 FEAT_HANDLE_UV_SEPARATE, 590 FEAT_ATTR2, 591 FEAT_CPR, 592 FEAT_PRELOAD, 593 FEAT_FIR_COEF_V, 594 FEAT_ALPHA_FREE_ZORDER, 595 FEAT_FIFO_MERGE, 596 FEAT_BURST_2D, 597}; 598 599static const enum dss_feat_id omap5_dss_feat_list[] = { 600 FEAT_MGR_LCD2, 601 FEAT_MGR_LCD3, 602 FEAT_CORE_CLK_DIV, 603 FEAT_LCD_CLK_SRC, 604 FEAT_DSI_DCS_CMD_CONFIG_VC, 605 FEAT_DSI_VC_OCP_WIDTH, 606 FEAT_DSI_GNQ, 607 FEAT_HDMI_CTS_SWMODE, 608 FEAT_HDMI_AUDIO_USE_MCLK, 609 FEAT_HANDLE_UV_SEPARATE, 610 FEAT_ATTR2, 611 FEAT_CPR, 612 FEAT_PRELOAD, 613 FEAT_FIR_COEF_V, 614 FEAT_ALPHA_FREE_ZORDER, 615 FEAT_FIFO_MERGE, 616 FEAT_BURST_2D, 617 FEAT_DSI_PHY_DCC, 618 FEAT_MFLAG, 619}; 620 621/* OMAP2 DSS Features */ 622static const struct omap_dss_features omap2_dss_features = { 623 .reg_fields = omap2_dss_reg_fields, 624 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), 625 626 .features = omap2_dss_feat_list, 627 .num_features = ARRAY_SIZE(omap2_dss_feat_list), 628 629 .num_mgrs = 2, 630 .num_ovls = 3, 631 .supported_displays = omap2_dss_supported_displays, 632 .supported_outputs = omap2_dss_supported_outputs, 633 .supported_color_modes = omap2_dss_supported_color_modes, 634 .overlay_caps = omap2_dss_overlay_caps, 635 .clksrc_names = omap2_dss_clk_source_names, 636 .dss_params = omap2_dss_param_range, 637 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 638 .buffer_size_unit = 1, 639 .burst_size_unit = 8, 640}; 641 642/* OMAP3 DSS Features */ 643static const struct omap_dss_features omap3430_dss_features = { 644 .reg_fields = omap3_dss_reg_fields, 645 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 646 647 .features = omap3430_dss_feat_list, 648 .num_features = ARRAY_SIZE(omap3430_dss_feat_list), 649 650 .num_mgrs = 2, 651 .num_ovls = 3, 652 .supported_displays = omap3430_dss_supported_displays, 653 .supported_outputs = omap3430_dss_supported_outputs, 654 .supported_color_modes = omap3_dss_supported_color_modes, 655 .overlay_caps = omap3430_dss_overlay_caps, 656 .clksrc_names = omap3_dss_clk_source_names, 657 .dss_params = omap3_dss_param_range, 658 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 659 .buffer_size_unit = 1, 660 .burst_size_unit = 8, 661}; 662 663/* 664 * AM35xx DSS Features. This is basically OMAP3 DSS Features without the 665 * vdds_dsi regulator. 666 */ 667static const struct omap_dss_features am35xx_dss_features = { 668 .reg_fields = omap3_dss_reg_fields, 669 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 670 671 .features = am35xx_dss_feat_list, 672 .num_features = ARRAY_SIZE(am35xx_dss_feat_list), 673 674 .num_mgrs = 2, 675 .num_ovls = 3, 676 .supported_displays = omap3430_dss_supported_displays, 677 .supported_outputs = omap3430_dss_supported_outputs, 678 .supported_color_modes = omap3_dss_supported_color_modes, 679 .overlay_caps = omap3430_dss_overlay_caps, 680 .clksrc_names = omap3_dss_clk_source_names, 681 .dss_params = omap3_dss_param_range, 682 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 683 .buffer_size_unit = 1, 684 .burst_size_unit = 8, 685}; 686 687static const struct omap_dss_features am43xx_dss_features = { 688 .reg_fields = am43xx_dss_reg_fields, 689 .num_reg_fields = ARRAY_SIZE(am43xx_dss_reg_fields), 690 691 .features = am43xx_dss_feat_list, 692 .num_features = ARRAY_SIZE(am43xx_dss_feat_list), 693 694 .num_mgrs = 1, 695 .num_ovls = 3, 696 .supported_displays = am43xx_dss_supported_displays, 697 .supported_outputs = am43xx_dss_supported_outputs, 698 .supported_color_modes = omap3_dss_supported_color_modes, 699 .overlay_caps = omap3430_dss_overlay_caps, 700 .clksrc_names = omap2_dss_clk_source_names, 701 .dss_params = am43xx_dss_param_range, 702 .supported_rotation_types = OMAP_DSS_ROT_DMA, 703 .buffer_size_unit = 1, 704 .burst_size_unit = 8, 705}; 706 707static const struct omap_dss_features omap3630_dss_features = { 708 .reg_fields = omap3_dss_reg_fields, 709 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 710 711 .features = omap3630_dss_feat_list, 712 .num_features = ARRAY_SIZE(omap3630_dss_feat_list), 713 714 .num_mgrs = 2, 715 .num_ovls = 3, 716 .supported_displays = omap3630_dss_supported_displays, 717 .supported_outputs = omap3630_dss_supported_outputs, 718 .supported_color_modes = omap3_dss_supported_color_modes, 719 .overlay_caps = omap3630_dss_overlay_caps, 720 .clksrc_names = omap3_dss_clk_source_names, 721 .dss_params = omap3_dss_param_range, 722 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 723 .buffer_size_unit = 1, 724 .burst_size_unit = 8, 725}; 726 727/* OMAP4 DSS Features */ 728/* For OMAP4430 ES 1.0 revision */ 729static const struct omap_dss_features omap4430_es1_0_dss_features = { 730 .reg_fields = omap4_dss_reg_fields, 731 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 732 733 .features = omap4430_es1_0_dss_feat_list, 734 .num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list), 735 736 .num_mgrs = 3, 737 .num_ovls = 4, 738 .num_wbs = 1, 739 .supported_displays = omap4_dss_supported_displays, 740 .supported_outputs = omap4_dss_supported_outputs, 741 .supported_color_modes = omap4_dss_supported_color_modes, 742 .overlay_caps = omap4_dss_overlay_caps, 743 .clksrc_names = omap4_dss_clk_source_names, 744 .dss_params = omap4_dss_param_range, 745 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 746 .buffer_size_unit = 16, 747 .burst_size_unit = 16, 748}; 749 750/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */ 751static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { 752 .reg_fields = omap4_dss_reg_fields, 753 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 754 755 .features = omap4430_es2_0_1_2_dss_feat_list, 756 .num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list), 757 758 .num_mgrs = 3, 759 .num_ovls = 4, 760 .num_wbs = 1, 761 .supported_displays = omap4_dss_supported_displays, 762 .supported_outputs = omap4_dss_supported_outputs, 763 .supported_color_modes = omap4_dss_supported_color_modes, 764 .overlay_caps = omap4_dss_overlay_caps, 765 .clksrc_names = omap4_dss_clk_source_names, 766 .dss_params = omap4_dss_param_range, 767 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 768 .buffer_size_unit = 16, 769 .burst_size_unit = 16, 770}; 771 772/* For all the other OMAP4 versions */ 773static const struct omap_dss_features omap4_dss_features = { 774 .reg_fields = omap4_dss_reg_fields, 775 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 776 777 .features = omap4_dss_feat_list, 778 .num_features = ARRAY_SIZE(omap4_dss_feat_list), 779 780 .num_mgrs = 3, 781 .num_ovls = 4, 782 .num_wbs = 1, 783 .supported_displays = omap4_dss_supported_displays, 784 .supported_outputs = omap4_dss_supported_outputs, 785 .supported_color_modes = omap4_dss_supported_color_modes, 786 .overlay_caps = omap4_dss_overlay_caps, 787 .clksrc_names = omap4_dss_clk_source_names, 788 .dss_params = omap4_dss_param_range, 789 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 790 .buffer_size_unit = 16, 791 .burst_size_unit = 16, 792}; 793 794/* OMAP5 DSS Features */ 795static const struct omap_dss_features omap5_dss_features = { 796 .reg_fields = omap5_dss_reg_fields, 797 .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields), 798 799 .features = omap5_dss_feat_list, 800 .num_features = ARRAY_SIZE(omap5_dss_feat_list), 801 802 .num_mgrs = 4, 803 .num_ovls = 4, 804 .supported_displays = omap5_dss_supported_displays, 805 .supported_outputs = omap5_dss_supported_outputs, 806 .supported_color_modes = omap4_dss_supported_color_modes, 807 .overlay_caps = omap4_dss_overlay_caps, 808 .clksrc_names = omap5_dss_clk_source_names, 809 .dss_params = omap5_dss_param_range, 810 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 811 .buffer_size_unit = 16, 812 .burst_size_unit = 16, 813}; 814 815/* Functions returning values related to a DSS feature */ 816int dss_feat_get_num_mgrs(void) 817{ 818 return omap_current_dss_features->num_mgrs; 819} 820EXPORT_SYMBOL(dss_feat_get_num_mgrs); 821 822int dss_feat_get_num_ovls(void) 823{ 824 return omap_current_dss_features->num_ovls; 825} 826EXPORT_SYMBOL(dss_feat_get_num_ovls); 827 828int dss_feat_get_num_wbs(void) 829{ 830 return omap_current_dss_features->num_wbs; 831} 832 833unsigned long dss_feat_get_param_min(enum dss_range_param param) 834{ 835 return omap_current_dss_features->dss_params[param].min; 836} 837 838unsigned long dss_feat_get_param_max(enum dss_range_param param) 839{ 840 return omap_current_dss_features->dss_params[param].max; 841} 842 843enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) 844{ 845 return omap_current_dss_features->supported_displays[channel]; 846} 847EXPORT_SYMBOL(dss_feat_get_supported_displays); 848 849enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel) 850{ 851 return omap_current_dss_features->supported_outputs[channel]; 852} 853EXPORT_SYMBOL(dss_feat_get_supported_outputs); 854 855enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) 856{ 857 return omap_current_dss_features->supported_color_modes[plane]; 858} 859EXPORT_SYMBOL(dss_feat_get_supported_color_modes); 860 861enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane) 862{ 863 return omap_current_dss_features->overlay_caps[plane]; 864} 865 866bool dss_feat_color_mode_supported(enum omap_plane plane, 867 enum omap_color_mode color_mode) 868{ 869 return omap_current_dss_features->supported_color_modes[plane] & 870 color_mode; 871} 872 873const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id) 874{ 875 return omap_current_dss_features->clksrc_names[id]; 876} 877 878u32 dss_feat_get_buffer_size_unit(void) 879{ 880 return omap_current_dss_features->buffer_size_unit; 881} 882 883u32 dss_feat_get_burst_size_unit(void) 884{ 885 return omap_current_dss_features->burst_size_unit; 886} 887 888/* DSS has_feature check */ 889bool dss_has_feature(enum dss_feat_id id) 890{ 891 int i; 892 const enum dss_feat_id *features = omap_current_dss_features->features; 893 const int num_features = omap_current_dss_features->num_features; 894 895 for (i = 0; i < num_features; i++) { 896 if (features[i] == id) 897 return true; 898 } 899 900 return false; 901} 902 903void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end) 904{ 905 if (id >= omap_current_dss_features->num_reg_fields) 906 BUG(); 907 908 *start = omap_current_dss_features->reg_fields[id].start; 909 *end = omap_current_dss_features->reg_fields[id].end; 910} 911 912bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type) 913{ 914 return omap_current_dss_features->supported_rotation_types & rot_type; 915} 916 917void dss_features_init(enum omapdss_version version) 918{ 919 switch (version) { 920 case OMAPDSS_VER_OMAP24xx: 921 omap_current_dss_features = &omap2_dss_features; 922 break; 923 924 case OMAPDSS_VER_OMAP34xx_ES1: 925 case OMAPDSS_VER_OMAP34xx_ES3: 926 omap_current_dss_features = &omap3430_dss_features; 927 break; 928 929 case OMAPDSS_VER_OMAP3630: 930 omap_current_dss_features = &omap3630_dss_features; 931 break; 932 933 case OMAPDSS_VER_OMAP4430_ES1: 934 omap_current_dss_features = &omap4430_es1_0_dss_features; 935 break; 936 937 case OMAPDSS_VER_OMAP4430_ES2: 938 omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; 939 break; 940 941 case OMAPDSS_VER_OMAP4: 942 omap_current_dss_features = &omap4_dss_features; 943 break; 944 945 case OMAPDSS_VER_OMAP5: 946 case OMAPDSS_VER_DRA7xx: 947 omap_current_dss_features = &omap5_dss_features; 948 break; 949 950 case OMAPDSS_VER_AM35xx: 951 omap_current_dss_features = &am35xx_dss_features; 952 break; 953 954 case OMAPDSS_VER_AM43xx: 955 omap_current_dss_features = &am43xx_dss_features; 956 break; 957 958 default: 959 DSSWARN("Unsupported OMAP version"); 960 break; 961 } 962} 963