Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "dm_services.h"
0027 
0028 /* include DCE11 register header files */
0029 #include "dce/dce_11_0_d.h"
0030 #include "dce/dce_11_0_sh_mask.h"
0031 
0032 #include "dce110_transform_v.h"
0033 
0034 static void power_on_lut(struct transform *xfm,
0035     bool power_on, bool inputgamma, bool regamma)
0036 {
0037     uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
0038     int i;
0039 
0040     if (power_on) {
0041         if (inputgamma)
0042             set_reg_field_value(
0043                 value,
0044                 1,
0045                 DCFEV_MEM_PWR_CTRL,
0046                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
0047         if (regamma)
0048             set_reg_field_value(
0049                 value,
0050                 1,
0051                 DCFEV_MEM_PWR_CTRL,
0052                 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
0053     } else {
0054         if (inputgamma)
0055             set_reg_field_value(
0056                 value,
0057                 0,
0058                 DCFEV_MEM_PWR_CTRL,
0059                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
0060         if (regamma)
0061             set_reg_field_value(
0062                 value,
0063                 0,
0064                 DCFEV_MEM_PWR_CTRL,
0065                 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
0066     }
0067 
0068     dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
0069 
0070     for (i = 0; i < 3; i++) {
0071         value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
0072         if (get_reg_field_value(value,
0073                 DCFEV_MEM_PWR_CTRL,
0074                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
0075             get_reg_field_value(value,
0076                     DCFEV_MEM_PWR_CTRL,
0077                     COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
0078             break;
0079 
0080         udelay(2);
0081     }
0082 }
0083 
0084 static void set_bypass_input_gamma(struct dce_transform *xfm_dce)
0085 {
0086     uint32_t value;
0087 
0088     value = dm_read_reg(xfm_dce->base.ctx,
0089             mmCOL_MAN_INPUT_GAMMA_CONTROL1);
0090 
0091     set_reg_field_value(
0092                 value,
0093                 0,
0094                 COL_MAN_INPUT_GAMMA_CONTROL1,
0095                 INPUT_GAMMA_MODE);
0096 
0097     dm_write_reg(xfm_dce->base.ctx,
0098             mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
0099 }
0100 
0101 static void configure_regamma_mode(struct dce_transform *xfm_dce, uint32_t mode)
0102 {
0103     uint32_t value = 0;
0104 
0105     set_reg_field_value(
0106                 value,
0107                 mode,
0108                 GAMMA_CORR_CONTROL,
0109                 GAMMA_CORR_MODE);
0110 
0111     dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CONTROL, 0);
0112 }
0113 
0114 /*
0115  *****************************************************************************
0116  *  Function: regamma_config_regions_and_segments
0117  *
0118  *     build regamma curve by using predefined hw points
0119  *     uses interface parameters ,like EDID coeff.
0120  *
0121  * @param   : parameters   interface parameters
0122  *  @return void
0123  *
0124  *  @note
0125  *
0126  *  @see
0127  *
0128  *****************************************************************************
0129  */
0130 static void regamma_config_regions_and_segments(
0131     struct dce_transform *xfm_dce, const struct pwl_params *params)
0132 {
0133     const struct gamma_curve *curve;
0134     uint32_t value = 0;
0135 
0136     {
0137         set_reg_field_value(
0138             value,
0139             params->arr_points[0].custom_float_x,
0140             GAMMA_CORR_CNTLA_START_CNTL,
0141             GAMMA_CORR_CNTLA_EXP_REGION_START);
0142 
0143         set_reg_field_value(
0144             value,
0145             0,
0146             GAMMA_CORR_CNTLA_START_CNTL,
0147             GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
0148 
0149         dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
0150                 value);
0151     }
0152     {
0153         value = 0;
0154         set_reg_field_value(
0155             value,
0156             params->arr_points[0].custom_float_slope,
0157             GAMMA_CORR_CNTLA_SLOPE_CNTL,
0158             GAMMA_CORR_CNTLA_EXP_REGION_LINEAR_SLOPE);
0159 
0160         dm_write_reg(xfm_dce->base.ctx,
0161             mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
0162     }
0163     {
0164         value = 0;
0165         set_reg_field_value(
0166             value,
0167             params->arr_points[1].custom_float_x,
0168             GAMMA_CORR_CNTLA_END_CNTL1,
0169             GAMMA_CORR_CNTLA_EXP_REGION_END);
0170 
0171         dm_write_reg(xfm_dce->base.ctx,
0172             mmGAMMA_CORR_CNTLA_END_CNTL1, value);
0173     }
0174     {
0175         value = 0;
0176         set_reg_field_value(
0177             value,
0178             params->arr_points[1].custom_float_slope,
0179             GAMMA_CORR_CNTLA_END_CNTL2,
0180             GAMMA_CORR_CNTLA_EXP_REGION_END_BASE);
0181 
0182         set_reg_field_value(
0183             value,
0184             params->arr_points[1].custom_float_y,
0185             GAMMA_CORR_CNTLA_END_CNTL2,
0186             GAMMA_CORR_CNTLA_EXP_REGION_END_SLOPE);
0187 
0188         dm_write_reg(xfm_dce->base.ctx,
0189             mmGAMMA_CORR_CNTLA_END_CNTL2, value);
0190     }
0191 
0192     curve = params->arr_curve_points;
0193 
0194     {
0195         value = 0;
0196         set_reg_field_value(
0197             value,
0198             curve[0].offset,
0199             GAMMA_CORR_CNTLA_REGION_0_1,
0200             GAMMA_CORR_CNTLA_EXP_REGION0_LUT_OFFSET);
0201 
0202         set_reg_field_value(
0203             value,
0204             curve[0].segments_num,
0205             GAMMA_CORR_CNTLA_REGION_0_1,
0206             GAMMA_CORR_CNTLA_EXP_REGION0_NUM_SEGMENTS);
0207 
0208         set_reg_field_value(
0209             value,
0210             curve[1].offset,
0211             GAMMA_CORR_CNTLA_REGION_0_1,
0212             GAMMA_CORR_CNTLA_EXP_REGION1_LUT_OFFSET);
0213 
0214         set_reg_field_value(
0215             value,
0216             curve[1].segments_num,
0217             GAMMA_CORR_CNTLA_REGION_0_1,
0218             GAMMA_CORR_CNTLA_EXP_REGION1_NUM_SEGMENTS);
0219 
0220         dm_write_reg(
0221                 xfm_dce->base.ctx,
0222             mmGAMMA_CORR_CNTLA_REGION_0_1,
0223             value);
0224     }
0225 
0226     curve += 2;
0227     {
0228         value = 0;
0229         set_reg_field_value(
0230             value,
0231             curve[0].offset,
0232             GAMMA_CORR_CNTLA_REGION_2_3,
0233             GAMMA_CORR_CNTLA_EXP_REGION2_LUT_OFFSET);
0234 
0235         set_reg_field_value(
0236             value,
0237             curve[0].segments_num,
0238             GAMMA_CORR_CNTLA_REGION_2_3,
0239             GAMMA_CORR_CNTLA_EXP_REGION2_NUM_SEGMENTS);
0240 
0241         set_reg_field_value(
0242             value,
0243             curve[1].offset,
0244             GAMMA_CORR_CNTLA_REGION_2_3,
0245             GAMMA_CORR_CNTLA_EXP_REGION3_LUT_OFFSET);
0246 
0247         set_reg_field_value(
0248             value,
0249             curve[1].segments_num,
0250             GAMMA_CORR_CNTLA_REGION_2_3,
0251             GAMMA_CORR_CNTLA_EXP_REGION3_NUM_SEGMENTS);
0252 
0253         dm_write_reg(xfm_dce->base.ctx,
0254             mmGAMMA_CORR_CNTLA_REGION_2_3,
0255             value);
0256     }
0257 
0258     curve += 2;
0259     {
0260         value = 0;
0261         set_reg_field_value(
0262             value,
0263             curve[0].offset,
0264             GAMMA_CORR_CNTLA_REGION_4_5,
0265             GAMMA_CORR_CNTLA_EXP_REGION4_LUT_OFFSET);
0266 
0267         set_reg_field_value(
0268             value,
0269             curve[0].segments_num,
0270             GAMMA_CORR_CNTLA_REGION_4_5,
0271             GAMMA_CORR_CNTLA_EXP_REGION4_NUM_SEGMENTS);
0272 
0273         set_reg_field_value(
0274             value,
0275             curve[1].offset,
0276             GAMMA_CORR_CNTLA_REGION_4_5,
0277             GAMMA_CORR_CNTLA_EXP_REGION5_LUT_OFFSET);
0278 
0279         set_reg_field_value(
0280             value,
0281             curve[1].segments_num,
0282             GAMMA_CORR_CNTLA_REGION_4_5,
0283             GAMMA_CORR_CNTLA_EXP_REGION5_NUM_SEGMENTS);
0284 
0285         dm_write_reg(xfm_dce->base.ctx,
0286             mmGAMMA_CORR_CNTLA_REGION_4_5,
0287             value);
0288     }
0289 
0290     curve += 2;
0291     {
0292         value = 0;
0293         set_reg_field_value(
0294             value,
0295             curve[0].offset,
0296             GAMMA_CORR_CNTLA_REGION_6_7,
0297             GAMMA_CORR_CNTLA_EXP_REGION6_LUT_OFFSET);
0298 
0299         set_reg_field_value(
0300             value,
0301             curve[0].segments_num,
0302             GAMMA_CORR_CNTLA_REGION_6_7,
0303             GAMMA_CORR_CNTLA_EXP_REGION6_NUM_SEGMENTS);
0304 
0305         set_reg_field_value(
0306             value,
0307             curve[1].offset,
0308             GAMMA_CORR_CNTLA_REGION_6_7,
0309             GAMMA_CORR_CNTLA_EXP_REGION7_LUT_OFFSET);
0310 
0311         set_reg_field_value(
0312             value,
0313             curve[1].segments_num,
0314             GAMMA_CORR_CNTLA_REGION_6_7,
0315             GAMMA_CORR_CNTLA_EXP_REGION7_NUM_SEGMENTS);
0316 
0317         dm_write_reg(xfm_dce->base.ctx,
0318             mmGAMMA_CORR_CNTLA_REGION_6_7,
0319             value);
0320     }
0321 
0322     curve += 2;
0323     {
0324         value = 0;
0325         set_reg_field_value(
0326             value,
0327             curve[0].offset,
0328             GAMMA_CORR_CNTLA_REGION_8_9,
0329             GAMMA_CORR_CNTLA_EXP_REGION8_LUT_OFFSET);
0330 
0331         set_reg_field_value(
0332             value,
0333             curve[0].segments_num,
0334             GAMMA_CORR_CNTLA_REGION_8_9,
0335             GAMMA_CORR_CNTLA_EXP_REGION8_NUM_SEGMENTS);
0336 
0337         set_reg_field_value(
0338             value,
0339             curve[1].offset,
0340             GAMMA_CORR_CNTLA_REGION_8_9,
0341             GAMMA_CORR_CNTLA_EXP_REGION9_LUT_OFFSET);
0342 
0343         set_reg_field_value(
0344             value,
0345             curve[1].segments_num,
0346             GAMMA_CORR_CNTLA_REGION_8_9,
0347             GAMMA_CORR_CNTLA_EXP_REGION9_NUM_SEGMENTS);
0348 
0349         dm_write_reg(xfm_dce->base.ctx,
0350             mmGAMMA_CORR_CNTLA_REGION_8_9,
0351             value);
0352     }
0353 
0354     curve += 2;
0355     {
0356         value = 0;
0357         set_reg_field_value(
0358             value,
0359             curve[0].offset,
0360             GAMMA_CORR_CNTLA_REGION_10_11,
0361             GAMMA_CORR_CNTLA_EXP_REGION10_LUT_OFFSET);
0362 
0363         set_reg_field_value(
0364             value,
0365             curve[0].segments_num,
0366             GAMMA_CORR_CNTLA_REGION_10_11,
0367             GAMMA_CORR_CNTLA_EXP_REGION10_NUM_SEGMENTS);
0368 
0369         set_reg_field_value(
0370             value,
0371             curve[1].offset,
0372             GAMMA_CORR_CNTLA_REGION_10_11,
0373             GAMMA_CORR_CNTLA_EXP_REGION11_LUT_OFFSET);
0374 
0375         set_reg_field_value(
0376             value,
0377             curve[1].segments_num,
0378             GAMMA_CORR_CNTLA_REGION_10_11,
0379             GAMMA_CORR_CNTLA_EXP_REGION11_NUM_SEGMENTS);
0380 
0381         dm_write_reg(xfm_dce->base.ctx,
0382             mmGAMMA_CORR_CNTLA_REGION_10_11,
0383             value);
0384     }
0385 
0386     curve += 2;
0387     {
0388         value = 0;
0389         set_reg_field_value(
0390             value,
0391             curve[0].offset,
0392             GAMMA_CORR_CNTLA_REGION_12_13,
0393             GAMMA_CORR_CNTLA_EXP_REGION12_LUT_OFFSET);
0394 
0395         set_reg_field_value(
0396             value,
0397             curve[0].segments_num,
0398             GAMMA_CORR_CNTLA_REGION_12_13,
0399             GAMMA_CORR_CNTLA_EXP_REGION12_NUM_SEGMENTS);
0400 
0401         set_reg_field_value(
0402             value,
0403             curve[1].offset,
0404             GAMMA_CORR_CNTLA_REGION_12_13,
0405             GAMMA_CORR_CNTLA_EXP_REGION13_LUT_OFFSET);
0406 
0407         set_reg_field_value(
0408             value,
0409             curve[1].segments_num,
0410             GAMMA_CORR_CNTLA_REGION_12_13,
0411             GAMMA_CORR_CNTLA_EXP_REGION13_NUM_SEGMENTS);
0412 
0413         dm_write_reg(xfm_dce->base.ctx,
0414             mmGAMMA_CORR_CNTLA_REGION_12_13,
0415             value);
0416     }
0417 
0418     curve += 2;
0419     {
0420         value = 0;
0421         set_reg_field_value(
0422             value,
0423             curve[0].offset,
0424             GAMMA_CORR_CNTLA_REGION_14_15,
0425             GAMMA_CORR_CNTLA_EXP_REGION14_LUT_OFFSET);
0426 
0427         set_reg_field_value(
0428             value,
0429             curve[0].segments_num,
0430             GAMMA_CORR_CNTLA_REGION_14_15,
0431             GAMMA_CORR_CNTLA_EXP_REGION14_NUM_SEGMENTS);
0432 
0433         set_reg_field_value(
0434             value,
0435             curve[1].offset,
0436             GAMMA_CORR_CNTLA_REGION_14_15,
0437             GAMMA_CORR_CNTLA_EXP_REGION15_LUT_OFFSET);
0438 
0439         set_reg_field_value(
0440             value,
0441             curve[1].segments_num,
0442             GAMMA_CORR_CNTLA_REGION_14_15,
0443             GAMMA_CORR_CNTLA_EXP_REGION15_NUM_SEGMENTS);
0444 
0445         dm_write_reg(xfm_dce->base.ctx,
0446             mmGAMMA_CORR_CNTLA_REGION_14_15,
0447             value);
0448     }
0449 }
0450 
0451 static void program_pwl(struct dce_transform *xfm_dce,
0452         const struct pwl_params *params)
0453 {
0454     uint32_t value = 0;
0455 
0456     set_reg_field_value(
0457         value,
0458         7,
0459         GAMMA_CORR_LUT_WRITE_EN_MASK,
0460         GAMMA_CORR_LUT_WRITE_EN_MASK);
0461 
0462     dm_write_reg(xfm_dce->base.ctx,
0463         mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
0464 
0465     dm_write_reg(xfm_dce->base.ctx,
0466         mmGAMMA_CORR_LUT_INDEX, 0);
0467 
0468     /* Program REGAMMA_LUT_DATA */
0469     {
0470         const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
0471         uint32_t i = 0;
0472         const struct pwl_result_data *rgb =
0473                 params->rgb_resulted;
0474 
0475         while (i != params->hw_points_num) {
0476             dm_write_reg(xfm_dce->base.ctx, addr, rgb->red_reg);
0477             dm_write_reg(xfm_dce->base.ctx, addr, rgb->green_reg);
0478             dm_write_reg(xfm_dce->base.ctx, addr, rgb->blue_reg);
0479 
0480             dm_write_reg(xfm_dce->base.ctx, addr,
0481                 rgb->delta_red_reg);
0482             dm_write_reg(xfm_dce->base.ctx, addr,
0483                 rgb->delta_green_reg);
0484             dm_write_reg(xfm_dce->base.ctx, addr,
0485                 rgb->delta_blue_reg);
0486 
0487             ++rgb;
0488             ++i;
0489         }
0490     }
0491 }
0492 
0493 void dce110_opp_program_regamma_pwl_v(
0494     struct transform *xfm,
0495     const struct pwl_params *params)
0496 {
0497     struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
0498 
0499     /* Setup regions */
0500     regamma_config_regions_and_segments(xfm_dce, params);
0501 
0502     set_bypass_input_gamma(xfm_dce);
0503 
0504     /* Power on gamma LUT memory */
0505     power_on_lut(xfm, true, false, true);
0506 
0507     /* Program PWL */
0508     program_pwl(xfm_dce, params);
0509 
0510     /* program regamma config */
0511     configure_regamma_mode(xfm_dce, 1);
0512 
0513     /* Power return to auto back */
0514     power_on_lut(xfm, false, false, true);
0515 }
0516 
0517 void dce110_opp_power_on_regamma_lut_v(
0518     struct transform *xfm,
0519     bool power_on)
0520 {
0521     uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
0522 
0523     set_reg_field_value(
0524         value,
0525         0,
0526         DCFEV_MEM_PWR_CTRL,
0527         COL_MAN_GAMMA_CORR_MEM_PWR_FORCE);
0528 
0529     set_reg_field_value(
0530         value,
0531         power_on,
0532         DCFEV_MEM_PWR_CTRL,
0533         COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
0534 
0535     set_reg_field_value(
0536         value,
0537         0,
0538         DCFEV_MEM_PWR_CTRL,
0539         COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE);
0540 
0541     set_reg_field_value(
0542         value,
0543         power_on,
0544         DCFEV_MEM_PWR_CTRL,
0545         COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
0546 
0547     dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
0548 }
0549 
0550 void dce110_opp_set_regamma_mode_v(
0551     struct transform *xfm,
0552     enum opp_regamma mode)
0553 {
0554     // TODO: need to implement the function
0555 }