| /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ |
| #include "msm_drv.h" |
| #include "sde_kms.h" |
| #include "sde_hw_mdss.h" |
| #include "sde_hw_util.h" |
| |
| /* using a file static variables for debugfs access */ |
| static u32 sde_hw_util_log_mask = SDE_DBG_MASK_NONE; |
| |
| void sde_reg_write(struct sde_hw_blk_reg_map *c, |
| u32 reg_off, |
| u32 val, |
| const char *name) |
| { |
| /* don't need to mutex protect this */ |
| if (c->log_mask & sde_hw_util_log_mask) |
| SDE_DEBUG_DRIVER("[%s:0x%X] <= 0x%X\n", |
| name, c->blk_off + reg_off, val); |
| writel_relaxed(val, c->base_off + c->blk_off + reg_off); |
| } |
| |
| int sde_reg_read(struct sde_hw_blk_reg_map *c, u32 reg_off) |
| { |
| return readl_relaxed(c->base_off + c->blk_off + reg_off); |
| } |
| |
| u32 *sde_hw_util_get_log_mask_ptr(void) |
| { |
| return &sde_hw_util_log_mask; |
| } |
| |
| void sde_hw_csc_setup(struct sde_hw_blk_reg_map *c, |
| u32 csc_reg_off, |
| struct sde_csc_cfg *data, bool csc10) |
| { |
| static const u32 matrix_shift = 7; |
| u32 clamp_shift = csc10 ? 16 : 8; |
| u32 val; |
| |
| /* matrix coeff - convert S15.16 to S4.9 */ |
| val = ((data->csc_mv[0] >> matrix_shift) & 0x1FFF) | |
| (((data->csc_mv[1] >> matrix_shift) & 0x1FFF) << 16); |
| SDE_REG_WRITE(c, csc_reg_off, val); |
| val = ((data->csc_mv[2] >> matrix_shift) & 0x1FFF) | |
| (((data->csc_mv[3] >> matrix_shift) & 0x1FFF) << 16); |
| SDE_REG_WRITE(c, csc_reg_off + 0x4, val); |
| val = ((data->csc_mv[4] >> matrix_shift) & 0x1FFF) | |
| (((data->csc_mv[5] >> matrix_shift) & 0x1FFF) << 16); |
| SDE_REG_WRITE(c, csc_reg_off + 0x8, val); |
| val = ((data->csc_mv[6] >> matrix_shift) & 0x1FFF) | |
| (((data->csc_mv[7] >> matrix_shift) & 0x1FFF) << 16); |
| SDE_REG_WRITE(c, csc_reg_off + 0xc, val); |
| val = (data->csc_mv[8] >> matrix_shift) & 0x1FFF; |
| SDE_REG_WRITE(c, csc_reg_off + 0x10, val); |
| |
| /* Pre clamp */ |
| val = (data->csc_pre_lv[0] << clamp_shift) | data->csc_pre_lv[1]; |
| SDE_REG_WRITE(c, csc_reg_off + 0x14, val); |
| val = (data->csc_pre_lv[2] << clamp_shift) | data->csc_pre_lv[3]; |
| SDE_REG_WRITE(c, csc_reg_off + 0x18, val); |
| val = (data->csc_pre_lv[4] << clamp_shift) | data->csc_pre_lv[5]; |
| SDE_REG_WRITE(c, csc_reg_off + 0x1c, val); |
| |
| /* Post clamp */ |
| val = (data->csc_post_lv[0] << clamp_shift) | data->csc_post_lv[1]; |
| SDE_REG_WRITE(c, csc_reg_off + 0x20, val); |
| val = (data->csc_post_lv[2] << clamp_shift) | data->csc_post_lv[3]; |
| SDE_REG_WRITE(c, csc_reg_off + 0x24, val); |
| val = (data->csc_post_lv[4] << clamp_shift) | data->csc_post_lv[5]; |
| SDE_REG_WRITE(c, csc_reg_off + 0x28, val); |
| |
| /* Pre-Bias */ |
| SDE_REG_WRITE(c, csc_reg_off + 0x2c, data->csc_pre_bv[0]); |
| SDE_REG_WRITE(c, csc_reg_off + 0x30, data->csc_pre_bv[1]); |
| SDE_REG_WRITE(c, csc_reg_off + 0x34, data->csc_pre_bv[2]); |
| |
| /* Post-Bias */ |
| SDE_REG_WRITE(c, csc_reg_off + 0x38, data->csc_post_bv[0]); |
| SDE_REG_WRITE(c, csc_reg_off + 0x3c, data->csc_post_bv[1]); |
| SDE_REG_WRITE(c, csc_reg_off + 0x40, data->csc_post_bv[2]); |
| } |
| |
| /** |
| * _sde_copy_formats - copy formats from src_list to dst_list |
| * @dst_list: pointer to destination list where to copy formats |
| * @dst_list_size: size of destination list |
| * @dst_list_pos: starting position on the list where to copy formats |
| * @src_list: pointer to source list where to copy formats from |
| * @src_list_size: size of source list |
| * Return: number of elements populated |
| */ |
| uint32_t sde_copy_formats( |
| struct sde_format_extended *dst_list, |
| uint32_t dst_list_size, |
| uint32_t dst_list_pos, |
| const struct sde_format_extended *src_list, |
| uint32_t src_list_size) |
| { |
| uint32_t cur_pos, i; |
| |
| if (!dst_list || !src_list || (dst_list_pos >= (dst_list_size - 1))) |
| return 0; |
| |
| for (i = 0, cur_pos = dst_list_pos; |
| (cur_pos < (dst_list_size - 1)) && (i < src_list_size) |
| && src_list[i].fourcc_format; ++i, ++cur_pos) |
| dst_list[cur_pos] = src_list[i]; |
| |
| dst_list[cur_pos].fourcc_format = 0; |
| |
| return i; |
| } |