aboutsummaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra124/displayhack.c
diff options
context:
space:
mode:
authorJimmy Zhang <jimmzhang@nvidia.com>2014-03-10 12:42:05 -0700
committerMarc Jones <marc.jones@se-eng.com>2014-11-14 07:27:17 +0100
commitbd5925ab2dfb5bcdecba539b83827d7788bc6808 (patch)
treea2a508884d63c2059a9e8ae363238bb99da77bad /src/soc/nvidia/tegra124/displayhack.c
parent4e16a2ea17a1b104507aeed8fca9c35750728248 (diff)
t124: Clean up display init functions
The existing display init functions were translated from a script. The new code will play the same functions but are cleaner and readable and easier to be ported to new panel. BUG=none TEST=build nyan and boot up kernel. Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com> Original-Change-Id: Ic9983e57684a03e206efe3731968ec62905f4ee8 Original-Reviewed-on: https://chromium-review.googlesource.com/189518 Original-Commit-Queue: Jimmy Zhang <jimmzhang@nvidia.com> Original-Tested-by: Jimmy Zhang <jimmzhang@nvidia.com> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> (cherry picked from commit 5998f991ea3069d603443b93c2ebdcdcd04af961) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Squashed to pass abuild nyan: Fix the build for big and blaze. The display code for the tegra124 was cleaned up recently, but only the nyan device tree was updated to match the new code, not big's or blaze's. This change copies nyan's device tree over to those other two boards which will get them building again. The settings may not be correct, but they'll be no less correct than they were before. I also updated the copyright date for nyan. BUG=none TEST=Built for nyan, nyan_big, nyan_blaze. Booted on nyan_big and verified the panel wasn't damaged by the new display code or settings. BRANCH=None Original-Change-Id: I75055a01f9402b3a9de9a787a9d3e737d25bb515 Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/191364 Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org> Original-Commit-Queue: Gabe Black <gabeblack@chromium.org> Original-Tested-by: Gabe Black <gabeblack@chromium.org> (cherry picked from commit ea235f23df31b4ca8006dcdf3628eed096e062b9) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: Icdad74bf2d013c3677e1a3373b8f89fad99f616e Reviewed-on: http://review.coreboot.org/7454 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks <dhendrix@chromium.org>
Diffstat (limited to 'src/soc/nvidia/tegra124/displayhack.c')
-rw-r--r--src/soc/nvidia/tegra124/displayhack.c738
1 files changed, 0 insertions, 738 deletions
diff --git a/src/soc/nvidia/tegra124/displayhack.c b/src/soc/nvidia/tegra124/displayhack.c
deleted file mode 100644
index af0ac16673..0000000000
--- a/src/soc/nvidia/tegra124/displayhack.c
+++ /dev/null
@@ -1,738 +0,0 @@
-/* this is too ugly to be allowed to live. But it's what works for now. */
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <console/console.h>
-#include <arch/io.h>
-#include <stdint.h>
-#include <lib.h>
-#include <stdlib.h>
-#include <delay.h>
-#include <soc/addressmap.h>
-#include <device/device.h>
-#include <stdlib.h>
-#include <string.h>
-#include <cpu/cpu.h>
-#include <boot/tables.h>
-#include <cbmem.h>
-#include <soc/nvidia/tegra/dc.h>
-#include "clk_rst.h"
-#include <soc/clock.h>
-#include "chip.h"
-#include "sor.h"
-#include <soc/display.h>
-
-//#include <soc/nvidia/tegra/displayport.h>
-extern int dump;
-unsigned long READL(void *p);
-void WRITEL(unsigned long value, void *p);
-void debug_dpaux_print(u32 addr, u32 size);
-int dpaux_write(u32 addr, u32 size, u32 data);
-int dpaux_read(u32 addr, u32 size, u8 * data);
-
-#define DCA_WRITE(reg, val) \
- { \
- WRITEL(val, (void *)(TEGRA_ARM_DISPLAYA + (reg<<2))); \
- }
-#define DCA_READ_M_WRITE(reg, mask, val) \
- { \
- u32 _reg_val; \
- _reg_val = READL( (void *)(TEGRA_ARM_DISPLAYA + (reg<<2))); \
- _reg_val &= ~mask; \
- _reg_val |= val; \
- WRITEL(_reg_val, (void *)(TEGRA_ARM_DISPLAYA + (reg<<2))); \
- }
-
-#define SOR_WRITE(reg, val) \
- { \
- WRITEL(val, (void *)(TEGRA_ARM_SOR + (reg<<2))); \
- }
-
-#define SOR_READ(reg) READL((void *)(TEGRA_ARM_SOR + (reg<<2)))
-
-#define SOR_READ_M_WRITE(reg, mask, val) \
- { \
- u32 _reg_val; \
- _reg_val = READL((void *)(TEGRA_ARM_SOR + (reg<<2))); \
- _reg_val &= ~mask; \
- _reg_val |= val; \
- WRITEL(_reg_val, (void *)(TEGRA_ARM_SOR + (reg<<2))); \
- }
-
-#define DPAUX_WRITE(reg, val) \
- { \
- WRITEL(val, (void *)(TEGRA_ARM_DPAUX + (reg<<2))); \
- }
-#define DPAUX_READ(reg) READL((void *)(TEGRA_ARM_DPAUX + (reg<<2)))
-
-void init_dca_regs(void)
-{
- DCA_WRITE (DC_CMD_DISPLAY_WINDOW_HEADER_0, 0x000000F0);
- DCA_WRITE (DC_WIN_A_WIN_OPTIONS_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_BYTE_SWAP_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_BUFFER_CONTROL_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_COLOR_DEPTH_0, 0x0000000C);
-
- DCA_WRITE (DC_WIN_A_POSITION_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_SIZE_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_PRESCALED_SIZE_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_H_INITIAL_DDA_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_V_INITIAL_DDA_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_DDA_INCREMENT_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_LINE_STRIDE_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_DV_CONTROL_0, 0x00000000);
-
- DCA_WRITE (DC_WIN_A_BLEND_LAYER_CONTROL_0, 0x01000000);
- DCA_WRITE (DC_WIN_A_BLEND_MATCH_SELECT_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_BLEND_NOMATCH_SELECT_0, 0x00000000);
- DCA_WRITE (DC_WIN_A_BLEND_ALPHA_1BIT_0, 0x00000000);
-
- DCA_WRITE (DC_WINBUF_A_START_ADDR_HI_0, 0x00000000);
- DCA_WRITE (DC_WINBUF_A_ADDR_H_OFFSET_0, 0x00000000);
- DCA_WRITE (DC_WINBUF_A_ADDR_V_OFFSET_0, 0x00000000);
- DCA_WRITE (DC_CMD_DISPLAY_WINDOW_HEADER_0, 0x00000000);
-
- DCA_WRITE (DC_COM_CRC_CONTROL_0, 0x00000000);
- DCA_WRITE (DC_COM_CRC_CHECKSUM_0, 0x00000000);
- DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE0_0, 0x00000000);
- DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE1_0, 0x00000000);
- DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE2_0, 0x00510104);
- DCA_WRITE (DC_COM_PIN_OUTPUT_ENABLE3_0, 0x00000555);
-}
-
-static int dp_poll_register(void *addr, u32 exp_val, u32 mask, u32 timeout_ms)
-{
- u32 reg_val = 0;
-
- do {
- udelay(1000);
- reg_val = READL(addr);
- } while (((reg_val & mask) != exp_val) && (--timeout_ms > 0));
-
- if ((reg_val & mask) == exp_val)
- return 0; /* success */
- printk(BIOS_WARNING, "poll_register %p: timeout\n", addr);
- return timeout_ms;
-}
-
-static void dp_io_set_dpd(u32 power_down)
-{
- /*
- * power_down:
- * 0: out of Deep power down
- * 1: into deep power down
- */
- u32 val_reg;
-
- val_reg = READL((void *)(0x7000e400 + 0x1c4)); /* APBDEV_PMC_IO_DPD2_STATUS_0 */
- if ((((val_reg & DP_LVDS) >> DP_LVDS_SHIFT) & 1) == power_down) {
- printk(BIOS_DEBUG, "PAD already POWER=%d\n", 1 - power_down);
- return;
- }
-
- /* APBDEV_PMC_IO_DPD2_REQ_0: E_DPD = power on */
- WRITEL((DP_LVDS | ((1 + power_down) << 30)), (void *)(0x7000e400 + 0x1c0));
-
- dp_poll_register((void *)(0x7000e400 + 0x1C4), 0, DP_LVDS, 1000);
- /* APBDEV_PMC_IO_DPD2_STATUS_0 */
-}
-
-void dp_io_powerup(void)
-{
- SOR_WRITE(SOR_NV_PDISP_SOR_CLK_CNTRL_0, (6 << 2) | 2);//select PLLDP, lowest speed(6x)
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, 0x00800000); //set PDCAL
- SOR_WRITE(SOR_NV_PDISP_SOR_PLL0_0, 0x050003D5); //set PWR,VCOPD
- SOR_WRITE(SOR_NV_PDISP_SOR_PLL1_0, 0x00001100); //default
- SOR_WRITE(SOR_NV_PDISP_SOR_PLL2_0, 0x01C20000); //set AUX1,6,7,8; clr AUX2
- SOR_WRITE(SOR_NV_PDISP_SOR_PLL3_0, 0x38002220);
-
- /* Deassert E_DPD to enable core logic circuits, and wait for > 5us */
- dp_io_set_dpd(0);
- udelay(10);
-
- /* Deassert PDBG to enable bandgap, and wait for > 20us. */
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0,
- SOR_NV_PDISP_SOR_PLL2_0_AUX6_FIELD,
- (0 << SOR_NV_PDISP_SOR_PLL2_0_AUX6_SHIFT));
- udelay(25);
-
- /*
- * Enable the PLL/charge-pump/VCO, and wait for >200us for the PLL to
- * lock. Input Clock must be running and stable before PDPLL
- * de-assertion.
- */
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL0_0,
- SOR_NV_PDISP_SOR_PLL0_0_PWR_FIELD,
- (0 << SOR_NV_PDISP_SOR_PLL0_0_PWR_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL0_0,
- SOR_NV_PDISP_SOR_PLL0_0_VCOPD_FIELD,
- (0 << SOR_NV_PDISP_SOR_PLL0_0_VCOPD_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0,
- SOR_NV_PDISP_SOR_PLL2_0_AUX8_FIELD,
- (0 << SOR_NV_PDISP_SOR_PLL2_0_AUX8_SHIFT));
- udelay(210);
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0,
- SOR_NV_PDISP_SOR_PLL2_0_AUX7_FIELD,
- (0 << SOR_NV_PDISP_SOR_PLL2_0_AUX7_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_PLL2_0,
- SOR_NV_PDISP_SOR_PLL2_0_AUX9_FIELD,
- (1 << SOR_NV_PDISP_SOR_PLL2_0_AUX9_SHIFT));
- udelay(100);
-
-}
-
-static int dpaux_check(u32 bytes, u32 data, u32 mask)
-{
- u32 status = 0;
- u8 buf[16];
- u32 temp;
-
- DPAUX_WRITE(DPAUX_DP_AUXDATA_READ_W0, 0);
- status = dpaux_read(0x202, bytes, buf);
- if (status != 0)
- printk(BIOS_ERR, "******AuxRead Error:%04x: status %08x\n",
- 0x202, status);
- else {
- temp = DPAUX_READ(DPAUX_DP_AUXDATA_READ_W0);
- if ((temp & mask) != (data & mask)) {
- printk(BIOS_ERR, "AuxCheck ERROR:(r_data) %08x &"
- " (mask) %08x != (data) %08x & (mask) %08x\n",
- temp, mask, data, mask);
- return -1;
- } else {
- printk(BIOS_DEBUG, "AuxCheck PASS:(bytes=%d, "
- "data=%08x, mask=%08x):0x%08x\n",
- bytes, data, mask, temp);
- return 0;
- }
- }
- return -1;
-}
-
-/* Modify the drive parameters for DP. There are up to four DP
- * lanes. In principle, each lane can have different current,
- * pre-emphasis, and postcur values. Nobody individualizes them; every
- * single driver I've seen drives all the lanes to the same value
- * (across x86 and ARM code). Actualy adjusting them individually and
- * getting it all to work is probably a PhD thesis anyway. So, rather
- * than the very complex code we see many places, the people who wrote
- * this code realize: we can represent the 'volume' as a number in the
- * range 0..3, with '0' as the base and '3' as being 'not to exceed'.
- *
- * So they abstract the values away, take care of the proper values,
- * and set it all in one blow. Very nice. By far the easiest one of
- * these functions we've seen. Sure, they could have constants, but
- * nobody knows what PRE_EMPHASIS_3_5 and the other values actually
- * *mean* anyway. Well, the hardware guys might.
- */
-static void pattern_level(u32 current, u32 preemph, u32 postcur)
-{
- //calibrating required
- if (current == 0)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0, 0x20202020);
- if (current == 1)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0, 0x24242424);
- if (current == 2)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0, 0x30303030);
- if (current == 3)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0, 0x40404040);
- if (preemph == 0)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0, 0x00000000);
- if (preemph == 1)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0, 0x08080808);
- if (preemph == 2)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0, 0x10101010);
- if (preemph == 3)
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0, 0x18181818);
- if (postcur == 0)
- SOR_WRITE(SOR_NV_PDISP_SOR_POSTCURSOR0_0, 0x00000000);
- if (postcur == 1)
- SOR_WRITE(SOR_NV_PDISP_SOR_POSTCURSOR0_0, 0x04040404);
- if (postcur == 2)
- SOR_WRITE(SOR_NV_PDISP_SOR_POSTCURSOR0_0, 0x08080808);
- if (postcur == 3)
- SOR_WRITE(SOR_NV_PDISP_SOR_POSTCURSOR0_0, 0x10101010);
-}
-
-static int dp_training(u32 level, u32 check, u32 speed)
-{
- /* The levels are one of four choices. This code
- * packs them into the three lowest nibl's. We may change this.
- */
- u32 dc_lv = level & 0x0f;
- u32 pe_lv = (level >> 4) & 0x0f;
- u32 pc_lv = (level >> 8) & 0x0f;
- u32 cnt = 0;
- u32 cfg, cfg_d = 0;
- u32 wcfg;
- u8 buf[16];
-
- while (cnt <= 5) {
- pattern_level(dc_lv, pe_lv, pc_lv);
- wcfg = (pe_lv << 3) | dc_lv;
- if (dc_lv == 3)
- wcfg = wcfg | 0x04;
- if (pe_lv == 3)
- wcfg = wcfg | 0x20;
- wcfg = wcfg | (wcfg << 8) | (wcfg << 16) | (wcfg << 24);
- dpaux_write(0x103, 4, wcfg);
- udelay(100);
- DPAUX_WRITE(DPAUX_DP_AUXDATA_READ_W0, 0);
- if (!dpaux_check(2, check, check))
- cnt = 100;
- else {
- dpaux_read(0x206, 1, buf);
- cfg = DPAUX_READ(DPAUX_DP_AUXDATA_READ_W0);
- cfg &= 0x00ff;
- if (cfg == cfg_d) {
- ++cnt;
- if (cnt > 5)
- printk(BIOS_ERR, "Error: link training FAILED\n");
- } else {
- cnt = 0;
- cfg_d = cfg;
- dc_lv = cfg & 0x3;
- pe_lv = (cfg >> 2) & 0x3;
- if (speed == 20) {
- dpaux_read(0x20C, 1, buf);
- cfg = DPAUX_READ(DPAUX_DP_AUXDATA_READ_W0);
- pc_lv = cfg & 0x3;
- } else {
- pc_lv = 0;
- }
- }
-
- }
- debug_dpaux_print(0x200, 16);
- }
-
- return ((pc_lv << 8) | (pe_lv << 4) | (dc_lv));
-
-}
-
-void dp_link_training(u32 lanes, u32 speed);
-void dp_link_training(u32 lanes, u32 speed)
-{
- u32 lane_on;
- u32 mask, level;
- u32 reg_val;
-
- printk(BIOS_DEBUG, "\nLink training start\n");
-
- switch (lanes) {
- case 1:
- lane_on = 0x04;
- break;
- case 2:
- lane_on = 0x06;
- break;
- case 4:
- lane_on = 0x0f;
- break;
- default:
- printk(BIOS_DEBUG, "dp: invalid lane count: %d\n",
- lanes);
- return;
- }
-
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, (0x008000000 | lane_on));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0,
- SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_VALUE_FIELD,
- (6 << SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_VALUE_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0,
- SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_FIELD,
- (1 << SOR_NV_PDISP_SOR_DP_PADCTL0_0_TX_PU_SHIFT));
- SOR_WRITE(SOR_NV_PDISP_SOR_LVDS_0, 0);
-
- SOR_WRITE(SOR_NV_PDISP_SOR_CLK_CNTRL_0, ((speed << 2) | 2));
- udelay(100 * 1000);
-
- sor_clock_start();
-
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_LINKCTL0_0,
- (((0xF >> (4 - lanes)) << 16) | 1));
-
- SOR_WRITE(SOR_NV_PDISP_SOR_LANE_SEQ_CTL_0, 0x80100000);
- printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_LANE_SEQ_CTL_0.DONE\n");
-
- dp_poll_register((void *)0x54540084, 0x00000000, 0x80000000, 1000);
-
- debug_dpaux_print(0x202, 4);
-
- printk(BIOS_DEBUG, "set link rate and lane number: %dMHz, %d lanes\n",
- (speed * 27), lanes);
-
- dpaux_write(0x100, 2, ((lanes << 8) | speed));
- printk(BIOS_DEBUG, "precharge lane 10us\n");
- reg_val = SOR_READ(SOR_NV_PDISP_SOR_DP_PADCTL0_0);
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, (0x000000f0 | reg_val));
- udelay(100 * 1000);
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, reg_val);
-
- printk(BIOS_DEBUG, "link training cr start\n");
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_TPG_0, 0x41414141);
- dpaux_write(0x102, 1, 0x21);
-
- mask = 0x0000ffff >> ((4 - lanes) * 4);
- level = 0;
- level = dp_training(level, 0x1111 & mask, speed);
- printk(BIOS_DEBUG, "level:%x\n", level);
-
- debug_dpaux_print(0x210, 16);
-
- printk(BIOS_DEBUG, "link training eq start\n");
- if (speed == 20) {
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_TPG_0, 0x43434343);
- dpaux_write(0x102, 1, 0x23);
- } else {
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_TPG_0, 0x42424242);
- dpaux_write(0x102, 1, 0x22);
- }
-
- level = dp_training(level, (0x7777 & mask) | 0x10000, speed);
- printk(BIOS_DEBUG, "level:%x\n", level);
-
- debug_dpaux_print(0x210, 16);
-
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_TPG_0, 0x50505050);
- dpaux_write(0x102, 1, 0);
- dpaux_write(0x600, 1, 1);
-
- debug_dpaux_print(0x200, 16);
- debug_dpaux_print(0x210, 16);
-
- printk(BIOS_DEBUG, "Link training done\n\n");
-}
-
-static u32 div_f(u32 a, u32 b, u32 one)
-{
- u32 d = (((a - (a / b * b)) * one) + (b / 2)) / b;
- return (d);
-}
-
-u32 dp_setup_timing(u32 width, u32 height)
-{
- u32 pclk_freq = 0;
-
- u32 PLL_FREQ = (12 / 12 * 283) / 1 / 2; /* 141.5 */
- u32 PLL_DIV = 2;
- u32 SYNC_WIDTH = (8 << 16) | 46;
- u32 BACK_PORCH = (6 << 16) | 44;
- u32 FRONT_PORCH = (6 << 16) | 44;
- u32 HSYNC_NEG = 1;
- u32 VSYNC_NEG = 1;
-
- u32 SHIFT_CLK_DIVIDER = PLL_DIV * 2 - 2;
- u32 DISP_ACTIVE = (height << 16) | width;
- u32 DISP_TOTAL = DISP_ACTIVE + SYNC_WIDTH + BACK_PORCH + FRONT_PORCH;
- u32 SYNC_END = SYNC_WIDTH - 0x10001;
- u32 BLANK_END = SYNC_END + BACK_PORCH;
- u32 BLANK_START = BLANK_END + DISP_ACTIVE;
- u32 TOTAL_PIXELS = (DISP_TOTAL & 0xffff) * (DISP_TOTAL >> 16);
-
- u32 PLL_FREQ_I, PLL_FREQ_F;
- u32 PCLK_FREQ_I, PCLK_FREQ_F;
- u32 FRATE_I, FRATE_F;
-
- PLL_FREQ = PLL_FREQ * 1000000;
- pclk_freq = PLL_FREQ / PLL_DIV;
- PLL_FREQ_I = PLL_FREQ / 1000000;
- PLL_FREQ_F = div_f(PLL_FREQ, 1000000, 100);
- PCLK_FREQ_I = PLL_FREQ / (PLL_DIV * 1000000);
- PCLK_FREQ_F = div_f(PLL_FREQ, PLL_DIV * 1000000, 100);
- FRATE_I = PLL_FREQ / (PLL_DIV * TOTAL_PIXELS);
- FRATE_F = div_f(PLL_FREQ, (PLL_DIV * TOTAL_PIXELS), 100);
- /* nv_bug 1021453 */
- BACK_PORCH = BACK_PORCH - 0x10000;
- FRONT_PORCH = FRONT_PORCH + 0x10000;
-
- printk(BIOS_DEBUG, "ACTIVE: %dx%d\n", (DISP_ACTIVE & 0xFFFF),
- (DISP_ACTIVE >> 16));
- printk(BIOS_DEBUG, "TOTAL: %dx%d\n", (DISP_TOTAL & 0xffff),
- (DISP_TOTAL >> 16));
- printk(BIOS_DEBUG, "PLL Freq: %d.%d MHz\n", PLL_FREQ_I, PLL_FREQ_F);
- printk(BIOS_DEBUG, "Pclk Freq: %d.%d MHz\n", PCLK_FREQ_I,
- PCLK_FREQ_F);
- printk(BIOS_DEBUG, "Frame Rate: %d.%d Hz\n", FRATE_I, FRATE_F);
- printk(BIOS_DEBUG, "\n");
-
- DCA_WRITE(DC_CMD_STATE_ACCESS_0, 0x00000004);
- DCA_WRITE(DC_DISP_DISP_CLOCK_CONTROL_0, SHIFT_CLK_DIVIDER);
- //Raster Timing
- DCA_WRITE(DC_DISP_DISP_TIMING_OPTIONS_0, 0x00000001);
- DCA_WRITE(DC_DISP_REF_TO_SYNC_0, 0x00010001);
- DCA_WRITE(DC_DISP_SYNC_WIDTH_0, SYNC_WIDTH);
- DCA_WRITE(DC_DISP_BACK_PORCH_0, BACK_PORCH);
- DCA_WRITE(DC_DISP_DISP_ACTIVE_0, DISP_ACTIVE);
- DCA_WRITE(DC_DISP_FRONT_PORCH_0, FRONT_PORCH);
-
- //REG(DC_DISP_DISP_WIN_OPTIONS_0, SOR_ENABLE , 1)
- DCA_READ_M_WRITE(DC_DISP_DISP_WIN_OPTIONS_0,
- DC_DISP_DISP_WIN_OPTIONS_0_SOR_ENABLE_FIELD,
- (1 << DC_DISP_DISP_WIN_OPTIONS_0_SOR_ENABLE_SHIFT));
-
- SOR_WRITE(SOR_NV_PDISP_HEAD_STATE1_0, DISP_TOTAL);
- SOR_WRITE(SOR_NV_PDISP_HEAD_STATE2_0, SYNC_END);
- SOR_WRITE(SOR_NV_PDISP_HEAD_STATE3_0, BLANK_END);
- SOR_WRITE(SOR_NV_PDISP_HEAD_STATE4_0, BLANK_START);
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_HSYNCPOL_FIELD,
- (HSYNC_NEG <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_HSYNCPOL_SHIFT));
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_VSYNCPOL_FIELD,
- (VSYNC_NEG <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_VSYNCPOL_SHIFT));
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_PROTOCOL_FIELD,
- (SOR_NV_PDISP_SOR_STATE1_0_ASY_PROTOCOL_DP_A <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_PROTOCOL_SHIFT));
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_CRCMODE_FIELD,
- (SOR_NV_PDISP_SOR_STATE1_0_ASY_CRCMODE_COMPLETE_RASTER <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_CRCMODE_SHIFT));
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_SUBOWNER_FIELD,
- (SOR_NV_PDISP_SOR_STATE1_0_ASY_SUBOWNER_NONE <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_SUBOWNER_SHIFT));
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_OWNER_FIELD,
- (SOR_NV_PDISP_SOR_STATE1_0_ASY_OWNER_HEAD0 <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_OWNER_SHIFT));
- return pclk_freq;
-}
-
-static u32 calc_config(u32 ts, u32 a, u32 b, u32 bpp)
-{
- u32 act_cnt = (ts * a) / b;
- u32 diff = (ts * a) - (act_cnt * b);
- u32 act_pol;
- u32 act_frac;
- u32 err;
- u32 water_mark;
-
- printk(BIOS_DEBUG, "calc_config ts %d a %d b %d bpp %d\n",
- ts, a, b, bpp);
- if (diff != 0) {
- if (diff > (b / 2)) {
- diff = b - diff;
- act_pol = 1;
- act_frac = (b + diff - 1) / diff;
- err = diff * act_frac - b;
- } else {
- act_pol = 0;
- act_frac = b / diff;
- err = b - (diff * act_frac);
- }
- if (act_frac > 15) {
- act_pol = 1 - act_pol;
- act_frac = 1;
- err = diff;
- }
- } else {
- act_pol = 1;
- act_frac = 1;
- err = 0;
- }
-
- if (bpp) {
- water_mark = (a * (b - a) * ts / (b * b)) + (2 * bpp / 8);
- if (water_mark > 30)
- water_mark = 30;
-
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_CONFIG0_0, 0x84000000);
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_CONFIG0_0,
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_ACTIVESYM_POLARITY_FIELD,
- (act_pol <<
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_ACTIVESYM_POLARITY_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_CONFIG0_0,
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_ACTIVESYM_FRAC_FIELD,
- (act_frac <<
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_ACTIVESYM_FRAC_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_CONFIG0_0,
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_ACTIVESYM_COUNT_FIELD,
- (act_cnt <<
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_ACTIVESYM_COUNT_SHIFT));
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_CONFIG0_0,
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_WATERMARK_FIELD,
- (water_mark <<
- SOR_NV_PDISP_SOR_DP_CONFIG0_0_WATERMARK_SHIFT));
-
- printk(BIOS_DEBUG,
- "SOR_DP_CONFIG0:TU,CNT,POL,FRAC,WMK,ERR=%d,%d,%d,%d,%d,%d/%d\n",
- ts, act_cnt, act_pol, act_frac, water_mark, err, b);
- }
- return (err);
-}
-
-static u32 dp_buf_config(u32 pclkfreq, u32 linkfreq, u32 lanes, u32 bpp)
-{
- //to avoid 32bit overflow
- u32 tusize = 0;
- u32 pf = pclkfreq;
- u32 lf = linkfreq;
- u32 i;
- u32 a, b;
- u32 min_err = 1000000000;
- u32 ts = 64;
- u32 c_err;
-
- printk(BIOS_DEBUG, "dp buf config pclkfreq %d linkfreq %d lanes %d bpp %d\n",
- pclkfreq, linkfreq, lanes, bpp);
- for (i = 2; i <= 7; ++i) {
- while (((pf / i * i) == pf) && ((lf / i * i) == lf)) {
- pf = pf / i;
- lf = lf / i;
- }
- }
-
- a = pf * bpp / 8;
- b = lf * lanes;
- printk(BIOS_DEBUG, "ratio:%d/%d\n", a, b);
- if (a > (b * 98 / 100))
- printk(BIOS_ERR, "Error:link speed not enough\n");
-
- //search best tusize
- //min_err = 1000000000;
- //ts = 64;
- while (ts >= 32) {
- c_err = calc_config(ts, a, b, 0);
- if (c_err < min_err) {
- if (c_err == 0) {
- tusize = ts;
- ts = 1;
- } else {
- min_err = c_err;
- tusize = ts;
- }
- }
- --ts;
- }
-
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_DP_LINKCTL0_0,
- SOR_NV_PDISP_SOR_DP_LINKCTL0_0_TUSIZE_FIELD,
- (tusize << SOR_NV_PDISP_SOR_DP_LINKCTL0_0_TUSIZE_SHIFT));
- calc_config(tusize, a, b, bpp);
-
- return (tusize);
-}
-
-/*
-void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr,
- u32 lane_count, u32 enhanced_framing, u32 panel_edp,
- u32 pclkfreq, u32 linkfreq);
-*/
-void dp_misc_setting(u32 panel_bpp, u32 width, u32 height, u32 winb_addr,
- u32 lane_count, u32 enhanced_framing, u32 panel_edp,
- u32 pclkfreq, u32 linkfreq)
-{
- u32 tusize;
- u32 linkctl;
-
- printk(BIOS_DEBUG, "%s: winb: 0x%08x, panel_bpp %d ",
- __func__, winb_addr, panel_bpp);
-
- if (panel_bpp == 18) {
- //0x54540010
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_FIELD,
- (SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_BPP_18_444 <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_SHIFT));
- }
- if (panel_bpp == 24) {
- SOR_READ_M_WRITE(SOR_NV_PDISP_SOR_STATE1_0,
- SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_FIELD,
- (SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_BPP_24_444 <<
- SOR_NV_PDISP_SOR_STATE1_0_ASY_PIXELDEPTH_SHIFT));
- }
-
- DCA_WRITE(DC_CMD_DISPLAY_WINDOW_HEADER_0, 0x00000010);
- DCA_WRITE(DC_WIN_A_SIZE_0, ((height << 16) | width));
- DCA_WRITE(DC_WIN_A_PRESCALED_SIZE_0,
- ((height << 16) | (width * SRC_BPP / 8)));
- DCA_WRITE(DC_WIN_A_LINE_STRIDE_0,
- ((width * SRC_BPP / 8 + 31) / 32 * 32));
- DCA_WRITE(DC_WIN_A_COLOR_DEPTH_0, COLORDEPTH);
- DCA_WRITE(DC_WINBUF_A_START_ADDR_LO_0, winb_addr);
- DCA_WRITE(DC_WIN_A_DDA_INCREMENT_0, 0x10001000);
-
- SOR_WRITE(SOR_NV_PDISP_SOR_CRC_CNTRL_0, 0x00000001);
- DCA_WRITE(DC_COM_CRC_CONTROL_0, 0x00000009); //CRC_ALWAYS+CRC_ENABLE
- DCA_WRITE(DC_COM_PIN_OUTPUT_ENABLE2_0, 0x00000000);
- DCA_WRITE(DC_COM_PIN_OUTPUT_ENABLE3_0, 0x00000000);
- DCA_WRITE(DC_DISP_DISP_SIGNAL_OPTIONS0_0, 0x00000000);
- DCA_WRITE(DC_DISP_BLEND_BACKGROUND_COLOR_0, COLOR_WHITE);
- DCA_WRITE(DC_CMD_DISPLAY_COMMAND_0, 0x00000020);
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_AUDIO_VBLANK_SYMBOLS_0, 0x00000e48);
-
- dpaux_write(0x101, 1, (enhanced_framing << 7) | lane_count);
- if (panel_edp)
- dpaux_write(0x10A, 1, 1);
-
- tusize =
- dp_buf_config(pclkfreq, (linkfreq * 1000000), lane_count, panel_bpp);
-
- linkctl =
- ((0xF >> (4 - lane_count)) << 16) | (enhanced_framing << 14) | (tusize
- << 2) |
- 1;
-
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_LINKCTL0_0, linkctl);
- SOR_WRITE(SOR_NV_PDISP_SOR_DP_SPARE0_0, ((panel_edp << 1) | 0x05));
-
- SOR_WRITE(SOR_NV_PDISP_SOR_PWR_0, 0x80000001);
- printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_PWR_0.DONE\n");
- dp_poll_register((void *)0x54540054, 0x00000000, 0x80000000, 1000);
- //SOR_NV_PDISP_SOR_PWR_0
- //sor_update
- SOR_WRITE(SOR_NV_PDISP_SOR_STATE0_0, 0x00000000);
- SOR_WRITE(SOR_NV_PDISP_SOR_SUPER_STATE1_0, 0x00000006);
- //sor_super_update
- SOR_WRITE(SOR_NV_PDISP_SOR_SUPER_STATE0_0, 0x00000000);
- SOR_WRITE(SOR_NV_PDISP_SOR_SUPER_STATE1_0, 0x0000000e);
- //sor_super_update
- SOR_WRITE(SOR_NV_PDISP_SOR_SUPER_STATE0_0, 0x00000000);
- printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_TEST_0.ATTACHED\n");
- dp_poll_register((void *)0x54540058, 0x00000400, 0x00000400, 1000);
- //SOR_NV_PDISP_SOR_TEST_0
-
- DCA_WRITE(DC_CMD_STATE_CONTROL_0, 0x00009f00);
- DCA_WRITE(DC_CMD_STATE_CONTROL_0, 0x0000009f);
- DCA_WRITE(DC_CMD_DISPLAY_POWER_CONTROL_0, 0x00050155);
-
- printk(BIOS_DEBUG, "Polling SOR_NV_PDISP_SOR_TEST_0.AWAKE\n");
- dp_poll_register((void *)0x54540058, 0x00000200, 0x00000300, 1000);
- //SOR_NV_PDISP_SOR_TEST_0
-
- // DCA_WRITE (DC_CMD_STATE_ACCESS_0 ,0);
- DCA_WRITE(DC_CMD_STATE_ACCESS_0, 4);
- DCA_WRITE(DC_CMD_STATE_CONTROL_0, 0x0000ffff);
-
- DCA_READ_M_WRITE(DC_WIN_A_WIN_OPTIONS_0,
- DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_FIELD,
- (DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_ENABLE <<
- DC_WIN_A_WIN_OPTIONS_0_A_WIN_ENABLE_SHIFT));
-}