blob: 13acb1e470f2a537b227900065643ba894386128 [file]
/*
* 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.
*
* 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.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Description:
*/
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/amlogic/media/registers/cpu_version.h>
#include "decoder_cpu_ver_info.h"
#include "../register/register.h"
#define AM_SUCCESS 0
#define MAJOR_ID_START AM_MESON_CPU_MAJOR_ID_M6
static enum AM_MESON_CPU_MAJOR_ID cpu_ver_id = AM_MESON_CPU_MAJOR_ID_MAX;
static int cpu_sub_id = 0;
static bool codec_dos_dev = 0; //to compat old dts
static struct dos_of_dev_s *platform_dos_dev = NULL;
static struct dos_of_dev_s dos_dev_data[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR_ID_START] = {
[AM_MESON_CPU_MAJOR_ID_M8B - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_M8B,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = false,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_1080P,
.hevc_max_resolution = RESOLUTION_1080P,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC,
},
[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_GXL,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_4K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_VP9,
},
[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_G12A,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667, //hevcb clk must be same with hevcf in g12a
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_4K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_G12B - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_G12B,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_4K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_GXLX2 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_GXLX2,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_4K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_SM1,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K, //support 8kp24
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_TL1,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K, //support 8kp24
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_TM2,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_C1 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_C1,
.reg_compat = NULL,
.is_vdec_canvas_support = true,
.fmt_support_flags = FMT_JPEG_ENC,
},
[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_SC2,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = false,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T5,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_4K, //unsupport vp9 & av1
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_AVS2,
},
[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T5D,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 667,
.max_hevcb_clock = 667,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_1080P,
.hevc_max_resolution = RESOLUTION_1080P, //unsupport 4k and avs2
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AV1,
},
[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T7,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.is_support_axi_ctrl = true,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_S4,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T3,
.reg_compat = t3_mm_registers_compat,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.is_support_rdma = true,
.is_support_mmu_copy = true,
.is_support_axi_ctrl = true,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K, //8kp30, rdma, mmu copy
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_S4D,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T5W,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_S5 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_S5,
.reg_compat = s5_mm_registers_compat, //register compact
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = true,
.is_support_axi_ctrl = true,
.hevc_stream_extra_shift = 8,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1_AVS3,
},
[AM_MESON_CPU_MAJOR_ID_T5M - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T5M,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.is_support_axi_ctrl = true,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_4K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
[AM_MESON_CPU_MAJOR_ID_T3X - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_T3X,
.reg_compat = s5_mm_registers_compat, //register compact
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.is_support_rdma = true,
.is_support_axi_ctrl = true,
.hevc_stream_extra_shift = 8,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1_AVS3,
},
[AM_MESON_CPU_MAJOR_ID_TXHD2 - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_TXHD2,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 500,
.max_hevcb_clock = 500,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_1080P,
.hevc_max_resolution = RESOLUTION_4K, //unsupport avs2,av1
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_VP9,
},
[AM_MESON_CPU_MAJOR_ID_S1A - MAJOR_ID_START] = {
.chip_id = AM_MESON_CPU_MAJOR_ID_S1A,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 500,
.max_hevcb_clock = 500,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = false,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_1080P,
.hevc_max_resolution = RESOLUTION_1080P,
.fmt_support_flags = FMT_HEVC | FMT_H264 | FMT_MPEG2 | FMT_MPEG4 | FMT_VC1,
},
};
/* sub id features */
static struct dos_of_dev_s dos_dev_sub_table[] = {
{ /* g12b revb */
.chip_id = AM_MESON_CPU_MINOR_ID_REVB_G12B,
.reg_compat = NULL,
.max_vdec_clock = 667,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800, //g12b revb hevc clk support 800mhz
.hevc_clk_combine_flag = true,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
},
{ /* tm2 revb */
.chip_id = AM_MESON_CPU_MINOR_ID_REVB_TM2,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = true,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
{
.chip_id = AM_MESON_CPU_MINOR_ID_S4_S805X2,
.reg_compat = NULL,
.max_vdec_clock = 500,
.max_hevcf_clock = 500,
.max_hevcb_clock = 500,
.hevc_clk_combine_flag = true,
.is_hw_parser_support = false,
.is_vdec_canvas_support = false,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.vdec_max_resolution = RESOLUTION_1080P,
.hevc_max_resolution = RESOLUTION_1080P,
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
},
{
.chip_id = AM_MESON_CPU_MINOR_ID_T7C,
.reg_compat = NULL,
.max_vdec_clock = 800,
.max_hevcf_clock = 800,
.max_hevcb_clock = 800,
.hevc_clk_combine_flag = false,
.is_hw_parser_support = false,
.is_vdec_canvas_support = true,
.is_support_h264_mmu = true,
.is_support_dual_core = false,
.is_support_axi_ctrl = true,
.vdec_max_resolution = RESOLUTION_4K,
.hevc_max_resolution = RESOLUTION_8K, //fixed endian issue
.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
}
};
/* dos device match table */
static const struct of_device_id cpu_ver_of_match[] = {
{
.compatible = "amlogic, cpu-major-id-axg",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_AXG - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-g12a",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-gxl",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-gxm",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_GXM - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-txl",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXL - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-txlx",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXLX - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-sm1",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-tl1",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-tm2",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-c1",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_C1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-sc2",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5d",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t7",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-s4",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t3",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-p1",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_P1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-s4d",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5w",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-s5",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S5 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5m",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5M - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t3x",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T3X - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-txhd2",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXHD2 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-s1a",
.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S1A - MAJOR_ID_START],
},
{},
};
static const struct of_device_id cpu_sub_id_of_match[] = {
{
.compatible = "amlogic, cpu-major-id-g12b-b",
.data = &dos_dev_sub_table[0],
},
{
.compatible = "amlogic, cpu-major-id-tm2-b",
.data = &dos_dev_sub_table[1],
},
{
.compatible = "amlogic, cpu-major-id-s4-805x2",
.data = &dos_dev_sub_table[2],
},
{
.compatible = "amlogic, cpu-major-id-t7c",
.data = &dos_dev_sub_table[3],
},
{}
};
static struct platform_device *get_dos_dev_from_dtb(void)
{
struct device_node *pnode = NULL;
pnode = of_find_node_by_name(NULL, CODEC_DOS_DEV_ID_NODE_NAME);
if (pnode == NULL) {
codec_dos_dev = false;
pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
if (pnode == NULL) {
pr_err("No find node.\n");
return NULL;
}
} else {
codec_dos_dev = true;
}
return of_find_device_by_node(pnode);
}
static struct dos_of_dev_s * get_dos_of_dev_data(struct platform_device *pdev)
{
const struct of_device_id *pmatch = NULL;
if (pdev == NULL)
return NULL;
pmatch = of_match_device(cpu_ver_of_match, &pdev->dev);
if (NULL == pmatch) {
pmatch = of_match_device(cpu_sub_id_of_match, &pdev->dev);
if (NULL == pmatch) {
pr_err("No find of_match_device\n");
return NULL;
}
}
return (struct dos_of_dev_s *)pmatch->data;
}
/* dos to get platform data */
static int dos_device_search_data(int id, int sub_id)
{
int i, j;
int sub_dev_id;
for (i = 0; i < ARRAY_SIZE(dos_dev_data); i++) {
if (id == dos_dev_data[i].chip_id) {
platform_dos_dev = &dos_dev_data[i];
pr_info("%s, get major %d dos dev data success\n", __func__, i);
if (sub_id) {
for (j = 0; j < ARRAY_SIZE(dos_dev_sub_table); j++) {
if (id == (dos_dev_sub_table[j].chip_id & MAJOR_ID_MASK)) {
sub_dev_id = (dos_dev_sub_table[j].chip_id & SUB_ID_MASK) >> 8;
if (sub_id == sub_dev_id) {
platform_dos_dev = &dos_dev_sub_table[j];
pr_info("%s, get sub %d dos dev data success\n", __func__, j);
}
}
}
}
}
}
if (platform_dos_dev)
return 0;
else
return -ENODEV;
}
struct platform_device *initial_dos_device(void)
{
struct platform_device *pdev = NULL;
struct dos_of_dev_s *of_dev_data;
pdev = get_dos_dev_from_dtb();
of_dev_data = get_dos_of_dev_data(pdev);
if (of_dev_data) {
cpu_ver_id = of_dev_data->chip_id & MAJOY_ID_MASK;
cpu_sub_id = (of_dev_data->chip_id & SUB_ID_MASK) >> 8;
platform_dos_dev = of_dev_data;
} else {
cpu_ver_id = (enum AM_MESON_CPU_MAJOR_ID)get_cpu_type();
cpu_sub_id = is_meson_rev_b() ? CHIP_REVB :
(is_meson_rev_c() ? CHIP_REVC : CHIP_REVA);
pr_info("get dos dev failed, id %d(%d), try to search\n",
cpu_ver_id, cpu_sub_id);
if (dos_device_search_data(cpu_ver_id, cpu_sub_id) < 0) {
pr_err("get dos device failed, dos maybe out of work\n");
//return NULL;
}
}
if ((cpu_ver_id == AM_MESON_CPU_MAJOR_ID_G12B) &&
(cpu_sub_id == CHIP_REVB))
cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1;
if (pdev && of_dev_data)
dos_register_probe(pdev, of_dev_data->reg_compat);
pr_info("initial_dos_device end, chip %d(%d)\n",
cpu_ver_id, cpu_sub_id);
return pdev;
}
EXPORT_SYMBOL(initial_dos_device);
enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void)
{
if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
initial_dos_device();
return cpu_ver_id;
}
EXPORT_SYMBOL(get_cpu_major_id);
int get_cpu_sub_id(void)
{
return cpu_sub_id;
}
EXPORT_SYMBOL(get_cpu_sub_id);
bool is_cpu_meson_revb(void)
{
if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
initial_dos_device();
return (cpu_sub_id == CHIP_REVB);
}
EXPORT_SYMBOL(is_cpu_meson_revb);
bool is_cpu_tm2_revb(void)
{
return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2)
&& (is_cpu_meson_revb()));
}
EXPORT_SYMBOL(is_cpu_tm2_revb);
bool is_cpu_s4_s805x2(void)
{
return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4)
&& (get_cpu_sub_id() == CHIP_REVX));
}
EXPORT_SYMBOL(is_cpu_s4_s805x2);
bool is_cpu_t7(void)
{
return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
&& (get_cpu_sub_id() != CHIP_REVC));
}
EXPORT_SYMBOL(is_cpu_t7);
bool is_cpu_t7c(void)
{
return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
&& (get_cpu_sub_id() == CHIP_REVC));
}
EXPORT_SYMBOL(is_cpu_t7c);
/*
feature from dos dev functions
*/
/*
bit0: force support no_parser;
bit1: force support all video format;
*/
#define FORCE_VDEC_NO_PARSER BIT(0)
#define FORCE_VDEC_SUPPORT_FMT BIT(1)
static u32 force_dos_support;
inline bool is_hevc_align32(int blkmod)
{
if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2) ||
(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S1A) ||
(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_G12A))
return true;
return false;
}
EXPORT_SYMBOL(is_hevc_align32);
inline bool is_support_new_dos_dev(void)
{
return codec_dos_dev;
}
EXPORT_SYMBOL(is_support_new_dos_dev);
inline struct dos_of_dev_s *dos_dev_get(void)
{
return platform_dos_dev;
}
EXPORT_SYMBOL(dos_dev_get);
/* vdec & hevc clock */
inline u32 vdec_max_clk_get(void)
{
return platform_dos_dev->max_vdec_clock;
}
EXPORT_SYMBOL(vdec_max_clk_get);
inline u32 hevcf_max_clk_get(void)
{
return platform_dos_dev->max_hevcf_clock;
}
EXPORT_SYMBOL(hevcf_max_clk_get);
inline u32 hevcb_max_clk_get(void)
{
return platform_dos_dev->max_hevcb_clock;
}
EXPORT_SYMBOL(hevcb_max_clk_get);
inline bool is_hevc_clk_combined(void)
{
return (platform_dos_dev->hevc_clk_combine_flag);
}
EXPORT_SYMBOL(is_hevc_clk_combined);
/* ressolution */
inline int vdec_is_support_4k(void)
{
if (platform_dos_dev->vdec_max_resolution > RESOLUTION_1080P)
return true;
else
return false;
}
EXPORT_SYMBOL(vdec_is_support_4k);
inline int hevc_is_support_4k(void)
{
if (platform_dos_dev->hevc_max_resolution > RESOLUTION_1080P)
return true;
else
return false;
}
EXPORT_SYMBOL(hevc_is_support_4k);
inline int hevc_is_support_8k(void)
{
if (platform_dos_dev->hevc_max_resolution > RESOLUTION_4K)
return true;
return false;
}
EXPORT_SYMBOL(hevc_is_support_8k);
inline bool is_oversize_vdec(int w, int h)
{
if (w < 0 || h < 0)
return true;
if (h != 0 && (w > platform_dos_dev->vdec_max_resolution / h))
return true;
return false;
}
EXPORT_SYMBOL(is_oversize_vdec);
inline bool is_oversize_hevc(int w, int h)
{
if (w < 0 || h < 0)
return true;
if (h != 0 && (w > platform_dos_dev->hevc_max_resolution / h))
return true;
return false;
}
EXPORT_SYMBOL(is_oversize_hevc);
inline bool is_support_no_parser(void)
{
return ((force_dos_support & FORCE_VDEC_NO_PARSER) ||
(!platform_dos_dev->is_hw_parser_support));
}
EXPORT_SYMBOL(is_support_no_parser);
/* vdec intra canvas feature */
inline bool is_support_vdec_canvas(void)
{
return (platform_dos_dev->is_vdec_canvas_support);
}
EXPORT_SYMBOL(is_support_vdec_canvas);
inline bool is_support_dual_core(void)
{
return (platform_dos_dev->is_support_dual_core);
}
EXPORT_SYMBOL(is_support_dual_core);
inline bool is_support_p010_mode(void)
{
return (platform_dos_dev->is_support_p010);
}
EXPORT_SYMBOL(is_support_p010_mode);
inline bool is_support_triple_write(void)
{
return (platform_dos_dev->is_support_triple_write);
}
EXPORT_SYMBOL(is_support_triple_write);
inline bool is_support_rdma(void)
{
return (platform_dos_dev->is_support_rdma);
}
EXPORT_SYMBOL(is_support_rdma);
inline bool is_support_mmu_copy(void)
{
return (platform_dos_dev->is_support_mmu_copy);
}
EXPORT_SYMBOL(is_support_mmu_copy);
inline bool is_support_axi_ctrl(void)
{
return platform_dos_dev->is_support_axi_ctrl;
}
EXPORT_SYMBOL(is_support_axi_ctrl);
inline bool is_support_format(int format)
{
if ((platform_dos_dev->fmt_support_flags == 0) ||
(force_dos_support & FORCE_VDEC_SUPPORT_FMT))
return true;
return ((1 << format) &
platform_dos_dev->fmt_support_flags);
}
EXPORT_SYMBOL(is_support_format);
inline int get_hevc_stream_extra_shift_bytes(void)
{
return platform_dos_dev->hevc_stream_extra_shift;
}
EXPORT_SYMBOL(get_hevc_stream_extra_shift_bytes);
void pr_dos_infos(void)
{
pr_info("dos device info:\n");
pr_info("chip id: 0x%x(0x%x)\n", cpu_ver_id, cpu_sub_id);
pr_info("max vdec clock: %03d MHz\n", vdec_max_clk_get());
pr_info("max hevcf clock: %03d MHz\n", hevcf_max_clk_get());
if (!is_hevc_clk_combined()) {
pr_info("max hevcb clock: %03d MHz\n", hevcb_max_clk_get());
}
pr_info("max vdec resolution : %s\n",
platform_dos_dev->vdec_max_resolution > RESOLUTION_1080P ? "4K":"1080P");
pr_info("max hevc resolution : %s\n",
platform_dos_dev->hevc_max_resolution < RESOLUTION_4K ? "1080P" :
(platform_dos_dev->hevc_max_resolution > RESOLUTION_4K ? "8K":"4K"));
pr_info("support no parser : %d\n", is_support_no_parser());
pr_info("support vdec canvas : %d\n", is_support_vdec_canvas());
pr_info("support dual core : %d\n", is_support_dual_core());
pr_info("support p010 mode : %d\n", is_support_p010_mode());
pr_info("support triple write: %d\n", is_support_triple_write());
pr_info("support rdma : %d\n", is_support_rdma());
pr_info("support mmu copy : %d\n", is_support_mmu_copy());
pr_info("support dos axi ctrl: %d\n", is_support_axi_ctrl());
pr_info("support format : 0x%x\n", platform_dos_dev->fmt_support_flags);
pr_info("hevc_stream_extra_shift_bytes: %d\n", get_hevc_stream_extra_shift_bytes());
}
EXPORT_SYMBOL(pr_dos_infos);
void dos_info_debug(void)
{
int i;
struct dos_of_dev_s *save = platform_dos_dev;
int save_major_id = cpu_ver_id;
int save_sub_id = cpu_sub_id;
for (i = 0; i < ARRAY_SIZE(dos_dev_data); i++) {
platform_dos_dev = &dos_dev_data[i];
if (platform_dos_dev->chip_id) {
cpu_ver_id = platform_dos_dev->chip_id;
pr_dos_infos();
pr_info("\n");
}
}
for (i = 0; i < ARRAY_SIZE(dos_dev_sub_table); i++) {
platform_dos_dev = &dos_dev_sub_table[i];
if (platform_dos_dev->chip_id) {
cpu_ver_id = platform_dos_dev->chip_id & MAJOR_ID_MASK;
cpu_sub_id = (platform_dos_dev->chip_id & SUB_ID_MASK) >> 8;
pr_dos_infos();
pr_info("\n");
}
}
platform_dos_dev = save;
cpu_ver_id = save_major_id;
cpu_sub_id = save_sub_id;
}
EXPORT_SYMBOL(dos_info_debug);
module_param(force_dos_support, uint, 0664);