blob: d50584a45faa67c6746ee95a45fae853c8dd474c [file] [log] [blame]
/*
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc. All rights reserved.
* Copyright 2017, 2018 NXP
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __IMX_COMMON_H__
#define __IMX_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include <gst/gst.h>
#include <string.h>
#define IMX_GST_PLUGIN_AUTHOR "Multimedia Team <shmmmw@freescale.com>"
#define IMX_GST_PLUGIN_PACKAGE_NAME "Freescle Gstreamer Multimedia Plugins"
#define IMX_GST_PLUGIN_PACKAGE_ORIG "http://www.freescale.com"
#define IMX_GST_PLUGIN_LICENSE "LGPL"
#define IMX_GST_PLUGIN_RANK (GST_RANK_PRIMARY+1)
#define IMX_GST_PLUGIN_DEFINE(name, description, initfunc)\
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,\
GST_VERSION_MINOR,\
name, \
description,\
initfunc,\
VERSION,\
IMX_GST_PLUGIN_LICENSE,\
IMX_GST_PLUGIN_PACKAGE_NAME, IMX_GST_PLUGIN_PACKAGE_ORIG)
#define CHIPCODE(a,b,c,d)( (((unsigned int)((a)))<<24) | (((unsigned int)((b)))<<16)|(((unsigned int)((c)))<<8)|(((unsigned int)((d)))))
typedef enum
{
CC_MX23 = CHIPCODE ('M', 'X', '2', '3'),
CC_MX25 = CHIPCODE ('M', 'X', '2', '5'),
CC_MX27 = CHIPCODE ('M', 'X', '2', '7'),
CC_MX28 = CHIPCODE ('M', 'X', '2', '8'),
CC_MX31 = CHIPCODE ('M', 'X', '3', '1'),
CC_MX35 = CHIPCODE ('M', 'X', '3', '5'),
CC_MX37 = CHIPCODE ('M', 'X', '3', '7'),
CC_MX50 = CHIPCODE ('M', 'X', '5', '0'),
CC_MX51 = CHIPCODE ('M', 'X', '5', '1'),
CC_MX53 = CHIPCODE ('M', 'X', '5', '3'),
CC_MX6Q = CHIPCODE ('M', 'X', '6', 'Q'),
CC_MX60 = CHIPCODE ('M', 'X', '6', '0'),
CC_MX6SL = CHIPCODE ('M', 'X', '6', '1'),
CC_MX6SX = CHIPCODE ('M', 'X', '6', '2'),
CC_MX6UL = CHIPCODE ('M', 'X', '6', '3'),
CC_MX6SLL = CHIPCODE ('M', 'X', '6', '4'),
CC_MX7D = CHIPCODE ('M', 'X', '7', 'D'),
CC_MX7ULP = CHIPCODE ('M', 'X', '7', 'U'),
CC_MX8 = CHIPCODE ('M', 'X', '8', '0'),
CC_MX8QM = CHIPCODE ('M', 'X', '8', '1'),
CC_MX8QXP = CHIPCODE ('M', 'X', '8', '3'),
CC_MX8M = CHIPCODE ('M', 'X', '8', '2'),
CC_MX8MM = CHIPCODE ('M', 'X', '8', '4'),
CC_UNKN = CHIPCODE ('U', 'N', 'K', 'N')
} CHIP_CODE;
typedef struct {
CHIP_CODE code;
int chip_num;
} CPU_INFO;
typedef struct {
CHIP_CODE code;
char *name;
} SOC_INFO;
typedef struct {
CHIP_CODE chip_name;
gboolean g3d;
gboolean g2d;
gboolean ipu;
gboolean pxp;
gboolean vpu;
gboolean dpu;
gboolean dcss;
} IMXV4l2FeatureMap;
typedef enum {
G3D = 1,
G2D,
IPU,
PXP,
VPU,
DPU,
DCSS
} CHIP_FEATURE;
#define HAS_G3D() check_feature(imx_chip_code(), G3D)
#define HAS_G2D() check_feature(imx_chip_code(), G2D)
#define HAS_IPU() check_feature(imx_chip_code(), IPU)
#define HAS_PXP() check_feature(imx_chip_code(), PXP)
#define HAS_VPU() check_feature(imx_chip_code(), VPU)
#define HAS_DPU() check_feature(imx_chip_code(), DPU)
#define HAS_DCSS() check_feature(imx_chip_code(), DCSS)
#define IS_HANTRO() ((CC_MX8M == imx_chip_code()) || (CC_MX8MM == imx_chip_code()) )
#define IS_AMPHION() ((CC_MX8QM == imx_chip_code()) || (CC_MX8QXP == imx_chip_code()))
#define IS_IMX8MM() (CC_MX8MM == imx_chip_code())
#define IS_IMX8MQ() (CC_MX8M == imx_chip_code())
#define IS_IMX8Q() ((CC_MX8QM == imx_chip_code()) || (CC_MX8QXP == imx_chip_code()))
#define IS_IMX6Q() (CC_MX6Q == imx_chip_code())
/* define rotate and flip glib enum for overlaysink and imxv4l2sink */
typedef enum
{
GST_IMX_ROTATION_0 = 0,
GST_IMX_ROTATION_90,
GST_IMX_ROTATION_180,
GST_IMX_ROTATION_270,
GST_IMX_ROTATION_HFLIP,
GST_IMX_ROTATION_VFLIP
}GstImxRotateMethod;
/*=============================================================================
FUNCTION: get_chipname
DESCRIPTION: To get chipname from /proc/cpuinfo
ARGUMENTS PASSED: STR of chipname
RETURN VALUE: chip code
=============================================================================*/
//*
static CPU_INFO cpu_info[] = {
{CC_MX23, 0x23},
{CC_MX25, 0x25},
{CC_MX27, 0x27},
{CC_MX28, 0x28},
{CC_MX31, 0x31},
{CC_MX35, 0x35},
{CC_MX37, 0x37},
{CC_MX50, 0x50},
{CC_MX51, 0x51},
{CC_MX53, 0x53},
{CC_MX6Q, 0x61},
{CC_MX6Q, 0x63},
{CC_MX60, 0x60}
};
static CHIP_CODE getChipCodeFromCpuinfo (void)
{
FILE *fp = NULL;
char buf[100], *p, *rev;
char chip_name[3];
int len = 0, i;
int chip_num = -1;
CHIP_CODE cc = CC_UNKN;
fp = fopen ("/proc/cpuinfo", "r");
if (fp == NULL) {
return cc;
}
while (!feof (fp)) {
p = fgets (buf, 100, fp);
p = strstr (buf, "Revision");
if (p != NULL) {
rev = index (p, ':');
if (rev != NULL) {
rev++;
chip_num = strtoul (rev, NULL, 16);
chip_num >>= 12;
break;
}
}
}
fclose (fp);
if (chip_num < 0) {
return cc;
}
int num = sizeof(cpu_info) / sizeof(CPU_INFO);
for(i=0; i<num; i++) {
if(chip_num == cpu_info[i].chip_num) {
cc = cpu_info[i].code;
break;
}
}
return cc;
}
static SOC_INFO soc_info[] = {
{CC_MX23, "i.MX23"},
{CC_MX25, "i.MX25"},
{CC_MX27, "i.MX27"},
{CC_MX28, "i.MX28"},
{CC_MX31, "i.MX31"},
{CC_MX35, "i.MX35"},
{CC_MX37, "i.MX37"},
{CC_MX50, "i.MX50"},
{CC_MX51, "i.MX51"},
{CC_MX53, "i.MX53"},
{CC_MX6Q, "i.MX6DL"},
{CC_MX6Q, "i.MX6Q"},
{CC_MX6Q, "i.MX6QP"},
{CC_MX6SL, "i.MX6SL"},
{CC_MX6SLL, "i.MX6SLL"},
{CC_MX6SX, "i.MX6SX"},
{CC_MX6UL, "i.MX6UL"},
{CC_MX6UL, "i.MX6ULL"},
{CC_MX7D, "i.MX7D"},
{CC_MX7ULP, "i.MX7ULP"},
{CC_MX8, "i.MX8DV"},
{CC_MX8QM, "i.MX8QM"},
{CC_MX8QXP, "i.MX8QXP"},
{CC_MX8M, "i.MX8MQ"},
{CC_MX8MM, "i.MX8MM"},
};
static CHIP_CODE getChipCodeFromSocid (void)
{
FILE *fp = NULL;
char soc_name[100];
CHIP_CODE code = CC_UNKN;
fp = fopen("/sys/devices/soc0/soc_id", "r");
if (fp == NULL) {
g_print("open /sys/devices/soc0/soc_id failed.\n");
return CC_UNKN;
}
if (fscanf(fp, "%100s", soc_name) != 1) {
g_print("fscanf soc_id failed.\n");
fclose(fp);
return CC_UNKN;
}
fclose(fp);
//GST_INFO("SOC is %s\n", soc_name);
int num = sizeof(soc_info) / sizeof(SOC_INFO);
int i;
for(i=0; i<num; i++) {
if(!strcmp(soc_name, soc_info[i].name)) {
code = soc_info[i].code;
break;
}
}
return code;
}
#define KERN_VER(a, b, c) (((a) << 16) + ((b) << 8) + (c))
static CHIP_CODE gimx_chip_code = CC_UNKN;
static CHIP_CODE imx_chip_code (void)
{
struct utsname sys_name;
int kv, kv_major, kv_minor, kv_rel;
char soc_name[255];
int rev_major, rev_minor;
int idx, num;
if (gimx_chip_code != CC_UNKN)
return gimx_chip_code;
if (uname(&sys_name) < 0) {
g_print("get kernel version via uname failed.\n");
return CC_UNKN;
}
if (sscanf(sys_name.release, "%d.%d.%d", &kv_major, &kv_minor, &kv_rel) != 3) {
g_print("sscanf kernel version failed.\n");
return CC_UNKN;
}
kv = ((kv_major << 16) + (kv_minor << 8) + kv_rel);
//GST_INFO("kernel:%s, %d.%d.%d\n", sys_name.release, kv_major, kv_minor, kv_rel);
if (kv < KERN_VER(3, 10, 0))
gimx_chip_code = getChipCodeFromCpuinfo();
else
gimx_chip_code = getChipCodeFromSocid();
return gimx_chip_code;
}
static IMXV4l2FeatureMap g_imxv4l2feature_maps[] = {
/* chip_name, g3d, g2d, ipu, pxp, vpu, dpu, dcss*/
{CC_MX6Q, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE},
{CC_MX6SL, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE},
{CC_MX6SLL, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE},
{CC_MX6SX, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE},
{CC_MX6UL, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE},
{CC_MX7D, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE},
{CC_MX7ULP, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE},
{CC_MX8, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE},
{CC_MX8QM, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE},
{CC_MX8QXP, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE},
{CC_MX8M, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE},
{CC_MX8MM, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE},
};
static gboolean check_feature(CHIP_CODE chip_name, CHIP_FEATURE feature)
{
int i;
gboolean ret = FALSE;
for (i=0; i<sizeof(g_imxv4l2feature_maps)/sizeof(IMXV4l2FeatureMap); i++) {
if ( chip_name== g_imxv4l2feature_maps[i].chip_name) {
switch (feature) {
case G3D:
ret = g_imxv4l2feature_maps[i].g3d;
break;
case G2D:
ret = g_imxv4l2feature_maps[i].g2d;
break;
case IPU:
ret = g_imxv4l2feature_maps[i].ipu;
break;
case PXP:
ret = g_imxv4l2feature_maps[i].pxp;
break;
case VPU:
ret = g_imxv4l2feature_maps[i].vpu;
break;
case DPU:
ret = g_imxv4l2feature_maps[i].dpu;
break;
case DCSS:
ret = g_imxv4l2feature_maps[i].dcss;
break;
default:
break;
}
break;
}
}
return ret;
}
#ifdef __cplusplus
}
#endif
#endif /* __IMX_COMMON_H__ */