hdmitx: using BL31 cmd to access hdmi reg

PD#149289: using BL31 cmd to access hdmi reg

1.hdmitx register may be accessed by kernel, bl30, bl31, etc...
To avoid concurrence issue, all should be only one port to access
hdmitx registers.Uniform kernel access to bl31.

2.optimize hdmitx driver style.

Change-Id: Ie5ae4b8bb8a641ccd39375b9addf9a8b01dcf464
Signed-off-by: Yi Zhou <yi.zhou@amlogic.com>
This commit is contained in:
Yi Zhou
2017-08-15 13:51:28 +08:00
parent 040673128e
commit 3209f568ba
8 changed files with 40 additions and 145 deletions

View File

@@ -13482,6 +13482,7 @@ F: drivers/amlogic/power/*
HDMITX OUTPUT DRIVER
M: Zongdong Jiao <zongdong.jiao@amlogic.com>
M: Yi Zhou <yi.zhou@amlogic.com>
S: Maintained
F: drivers/amlogic/media/vout/hdmitx/*
F: drivers/amlogic/media/vout/hdmitx/hdcp/*

View File

@@ -3028,6 +3028,16 @@ void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
}
static int amhdmitx_device_init(struct hdmitx_dev *hdmi_dev)
{
if (hdmi_dev == NULL)
return 1;
hdmi_dev->hdtx_dev = NULL;
return 0;
}
static int amhdmitx_probe(struct platform_device *pdev)
{
int r, ret = 0;
@@ -3040,6 +3050,11 @@ static int amhdmitx_probe(struct platform_device *pdev)
struct device_node *init_data;
#endif
hdmi_print(IMP, SYS "amhdmitx_init\n");
hdmi_print(IMP, SYS "Ver: %s\n", HDMITX_VER);
amhdmitx_device_init(&hdmitx_device);
hdmitx_device.hdtx_dev = &pdev->dev;
hdmitx_device.physical_addr = 0xffff;
/* init para for NULL protection */
@@ -3438,26 +3453,11 @@ static struct platform_driver amhdmitx_driver = {
}
};
static int amhdmitx_device_init(struct hdmitx_dev *hdmi_dev)
{
if (hdmi_dev == NULL)
return 1;
hdmi_dev->hdtx_dev = NULL;
return 0;
}
static int __init amhdmitx_init(void)
{
if (init_flag&INIT_FLAG_NOT_LOAD)
return 0;
hdmi_print(IMP, SYS "amhdmitx_init\n");
hdmi_print(IMP, SYS "Ver: %s\n", HDMITX_VER);
amhdmitx_device_init(&hdmitx_device);
if (platform_driver_register(&amhdmitx_driver)) {
hdmi_print(ERR, SYS
"failed to register amhdmitx module\n");

View File

@@ -1,2 +1,2 @@
obj-y += hdmi_tx_hw.o reg_ops.o sec_ops.o enc_cfg_hw.o hdmi_tx_ddc.o hdcpVerify.o
obj-y += hdmi_tx_hw.o reg_ops.o enc_cfg_hw.o hdmi_tx_ddc.o hdcpVerify.o
obj-y += hw_gxbb.o hw_gxtvbb.o hw_gxl.o hw_txlx.o hw_clk.o

View File

@@ -3120,10 +3120,6 @@ static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf)
hdmitx_wr_reg((unsigned int)adr, (unsigned int)value);
read_back = hdmitx_rd_reg(adr);
}
if (buf[1] == 'c') {
hdcp22_wr_reg((uint32_t)adr, (uint32_t)value);
read_back = hdcp22_rd_reg((uint32_t)adr);
}
hdmi_print(INF, "write %x to %s reg[%x]\n", value, "HDMI", adr);
/* Add read back function in order to judge writing is OK or NG. */
hdmi_print(INF, "Read Back %s reg[%x]=%x\n", "HDMI",
@@ -3132,8 +3128,6 @@ static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf)
ret = kstrtoul(tmpbuf+2, 16, &adr);
if (buf[1] == 'h')
value = hdmitx_rd_reg(adr);
if (buf[1] == 'c')
value = hdcp22_rd_reg((uint32_t)adr);
hdmi_print(INF, "%s reg[%x]=%x\n", "HDMI", adr, value);
}
}

View File

@@ -31,8 +31,6 @@ void hdmitx_rd_check_reg(unsigned int addr, unsigned int exp_data,
unsigned int mask);
unsigned long aocec_rd_reg(unsigned long addr);
void aocec_wr_reg(unsigned long addr, unsigned long data);
void hdcp22_wr_reg(uint32_t addr, uint32_t data);
uint32_t hdcp22_rd_reg(uint32_t addr);
int hdmitx_hdcp_opr(unsigned int val);
/* TOP-level wrapper registers addresses

View File

@@ -29,8 +29,6 @@ unsigned int hd_read_reg(unsigned int addr);
void hd_write_reg(unsigned int addr, unsigned int val);
void hd_set_reg_bits(unsigned int addr, unsigned int value, unsigned int offset,
unsigned int len);
void sec_reg_write(unsigned int *addr, unsigned int value);
unsigned int sec_reg_read(unsigned int *addr);
void init_reg_map(unsigned int type);
#define CBUS_REG_IDX 0

View File

@@ -200,38 +200,24 @@ void hd_set_reg_bits(unsigned int addr, unsigned int value,
hd_write_reg(addr, data32);
}
static DEFINE_SPINLOCK(reg_lock);
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
unsigned int hdmitx_rd_reg(unsigned int addr)
{
unsigned int data = 0;
unsigned long offset = (addr & DWC_OFFSET_MASK) >> 24;
unsigned long flags, fiq_flag;
if (addr & SEC_OFFSET) {
addr = addr & 0xffff;
sec_reg_write((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_HDMITX_ADDR_PORT_SEC + offset), addr);
sec_reg_write((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_HDMITX_ADDR_PORT_SEC + offset), addr);
data = sec_reg_read((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_HDMITX_DATA_PORT_SEC + offset));
} else {
addr = addr & 0xffff;
spin_lock_irqsave(&reg_lock, flags);
raw_local_save_flags(fiq_flag);
local_fiq_disable();
unsigned int data;
/*
* If addr is located at 0x5020 ~ 0x667e in DWC,
* then should operate twice
*/
hd_write_reg(P_HDMITX_ADDR_PORT + offset, addr);
hd_write_reg(P_HDMITX_ADDR_PORT + offset, addr);
data = hd_read_reg(P_HDMITX_DATA_PORT + offset);
data = hd_read_reg(P_HDMITX_DATA_PORT + offset);
register long x0 asm("x0") = 0x82000018;
register long x1 asm("x1") = (unsigned long)addr;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
"smc #0\n"
: "+r"(x0) : "r"(x1)
);
data = (unsigned int)(x0&0xffffffff);
raw_local_irq_restore(fiq_flag);
spin_unlock_irqrestore(&reg_lock, flags);
}
if (dbg_en)
pr_info("%s rd[0x%x] 0x%x\n", offset ? "DWC" : "TOP",
addr, data);
@@ -240,29 +226,19 @@ unsigned int hdmitx_rd_reg(unsigned int addr)
void hdmitx_wr_reg(unsigned int addr, unsigned int data)
{
unsigned long flags, fiq_flag;
unsigned long offset = (addr & DWC_OFFSET_MASK) >> 24;
register long x0 asm("x0") = 0x82000019;
register long x1 asm("x1") = (unsigned long)addr;
register long x2 asm("x2") = data;
if (addr & SEC_OFFSET) {
addr = addr & 0xffff;
sec_reg_write((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_HDMITX_ADDR_PORT_SEC + offset), addr);
sec_reg_write((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_HDMITX_ADDR_PORT_SEC + offset), addr);
sec_reg_write((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_HDMITX_DATA_PORT_SEC + offset), data);
} else {
addr = addr & 0xffff;
spin_lock_irqsave(&reg_lock, flags);
raw_local_save_flags(fiq_flag);
local_fiq_disable();
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
"smc #0\n"
: : "r"(x0), "r"(x1), "r"(x2)
);
hd_write_reg(P_HDMITX_ADDR_PORT + offset, addr);
hd_write_reg(P_HDMITX_ADDR_PORT + offset, addr);
hd_write_reg(P_HDMITX_DATA_PORT + offset, data);
raw_local_irq_restore(fiq_flag);
spin_unlock_irqrestore(&reg_lock, flags);
}
if (dbg_en)
pr_info("%s wr[0x%x] 0x%x\n", offset ? "DWC" : "TOP",
addr, data);
@@ -306,18 +282,6 @@ void hdmitx_rd_check_reg(unsigned int addr, unsigned int exp_data,
}
}
void hdcp22_wr_reg(uint32_t addr, uint32_t data)
{
sec_reg_write((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_ELP_ESM_HPI_REG_BASE + addr), data);
}
uint32_t hdcp22_rd_reg(uint32_t addr)
{
return (uint32_t)sec_reg_read((unsigned int *)(unsigned long)
TO_PHY_ADDR(P_ELP_ESM_HPI_REG_BASE + addr));
}
MODULE_PARM_DESC(dbg_en, "\n debug_level\n");
module_param(dbg_en, int, 0664);

View File

@@ -1,60 +0,0 @@
/*
* drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/sec_ops.c
*
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include "mach_reg.h"
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
void sec_reg_write(unsigned int *addr, unsigned int value)
{
register long x0 asm("x0") = 0x82000019;
register long x1 asm("x1") = (unsigned long)addr;
register long x2 asm("x2") = value;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
"smc #0\n"
: : "r"(x0), "r"(x1), "r"(x2)
);
}
unsigned int sec_reg_read(unsigned int *addr)
{
register long x0 asm("x0") = 0x82000018;
register long x1 asm("x1") = (unsigned long)addr;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
"smc #0\n"
: "+r"(x0) : "r"(x1)
);
return (unsigned int)(x0&0xffffffff);
}