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