blob: 975c8dc6ff2f3142b900734837a062bf8182030c [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* arch/arm/cpu/armv8/gxtvbb/hdmitx20/hdmitx_hdcp.c
*
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
*
*/
#include <asm/arch/io.h>
#include <common.h>
#include "hdmi_tx_reg.h"
// if the following bits are 0, then access HDMI IP Port will cause system hungup
#define GATE_NUM 2
static struct Hdmi_Gate_s{
unsigned short cbus_addr;
unsigned char gate_bit;
}hdmi_gate[GATE_NUM] = { {HHI_HDMI_CLK_CNTL, 8},
{HHI_GCLK_MPEG2 , 4},
};
// In order to prevent system hangup, add check_cts_hdmi_sys_clk_status() to check
static void check_cts_hdmi_sys_clk_status(void)
{
int i;
for (i = 0; i < GATE_NUM; i++) {
if (!(READ_CBUS_REG(hdmi_gate[i].cbus_addr) & (1<<hdmi_gate[i].gate_bit))) {
// printf("HDMI Gate Clock is off, turn on now\n");
WRITE_CBUS_REG_BITS(hdmi_gate[i].cbus_addr, 1, hdmi_gate[i].gate_bit, 1);
}
}
}
unsigned long hdmi_hdcp_rd_reg(unsigned long addr)
{
unsigned long data;
check_cts_hdmi_sys_clk_status();
WRITE_APB_REG(HDMI_ADDR_PORT, addr);
WRITE_APB_REG(HDMI_ADDR_PORT, addr);
data = READ_APB_REG(HDMI_DATA_PORT);
return (data);
}
void hdmi_hdcp_wr_reg(unsigned long addr, unsigned long data)
{
check_cts_hdmi_sys_clk_status();
WRITE_APB_REG(HDMI_ADDR_PORT, addr);
WRITE_APB_REG(HDMI_ADDR_PORT, addr);
WRITE_APB_REG(HDMI_DATA_PORT, data);
}
#define TX_HDCP_KSV_OFFSET 0x540
#define TX_HDCP_KSV_SIZE 5
// Must be done by system init
// In kenrel hdmi driver, it will get AKSV value
// If equals to 0, then kernel won't enable HDCP
extern int hdmi_hdcp_clear_ksv_ram(void);
int hdmi_hdcp_clear_ksv_ram(void)
{
int i;
for (i = 0; i < TX_HDCP_KSV_SIZE; i++) {
hdmi_hdcp_wr_reg(TX_HDCP_KSV_OFFSET + i, 0x00);
}
printf("clr h-ram\n");
return 0;
}