#!/usr/bin/python
# ------------------------------------------------------------------------------------
# FileName:  memory_cfg.py
# Copyright (c) 2008 - 2010 Shen Zhen Coship Electronics CO., LTD.
# 
# Version:       Ver 1.0
# Author:        wuzhengbing (wuzhengbing@coship.com)
#
# File Description:
#        st71xx platform memory config script
# 
# Modify History:
# Version     Date        Author          Description
# --------    ----------  --------        ------------
# 1.0         2008-12-16  wuzhengbing     Create
# 1.1         2008-12-24  wuzhengbing     increase AVMEM_SYS and driver partition size
# 1.2         2008-12-30  wuzhengbing     for mmp linux environment
# 1.3         2008-01-04  wangte          double video decoder avmem size if PIP mode
# 1.4         2009-01-04  wuzhengbing     memory in LMI_VID can be cached,correct some spell error
# 1.5         2009-01-21  wuzhengbing     reduced AVMEM size for SD video decoding,
#                                         increase os_partition size & PVR support
# 1.6         2009-06-12  wuzhengbing     increase avmem_sys for HD-DEI
#                                         increase driver_partition&ncache_partition for PVR
# 1.7         2009-06-17  wuzhengbing     set OFFSET_FOR_AV_FW to 5M for st7105
#                                         subtract audio used avmem when PIP mode
# 1.8         2010-03-22  wuzhengbing     add compatibility for ST5197
# 1.9         2010-07-22  wuzhengbing     st40R4.4.0 for st7105
# 2.0	      2010-07-27  hanshaoyang     add compatibility for ST5289
# ------------------------------------------------------------------------------------
# DO NOT modify this file if you don't know the result. 
# ------------------------------------------------------------------------------------

import ConfigParser, os, sys, re, logging

#const
M = 1024*1024
K = 1024

VERSION = '2.0'
DONOT_MODIFY_NOTICE = 'automatically created by memory_cfg.py, do not modify manually!'

class Partition:
    base = 0
    size = 0
    name = ''
    def __init__(self, name):
        self.name = name

#decode_avmem_requirement_table for st7100/7109
decode_avmem_requirement_table_st7100 = {
    #hd_disp    hd_mpeg2    hd_h264  avmem_sys  avmem_vid
    (0,         0,          0):      (20*M,         0),
    (0,         1,          0):      (25*M,         0),
    (0,         0,          1):      (50*M,         0),
    (0,         1,          1):      (50*M,         0),
    
    (1,         0,          0):      (22*M,         0),
    (1,         1,          0):      (34*M,         0),
    (1,         0,          1):      (60*M,         0),
    (1,         1,          1):      (60*M,         0)
    }

#decode_avmem_requirement_table for st7111 & st7105
decode_avmem_requirement_table_st71xx = {
    #hd_disp    hd_mpeg2    hd_h264  avmem_sys  
avmem_vid
    (0,         0,          0):      (20*M,         0),
    (0,         1,          0):      (25*M,         0),
    (0,         0,          1):      (50*M,        
 0),
    (0,         1,          1):      (50*M,         0),
    
    (1,         0,          0):      (22*M,         0),
    (1,         1,          0):      (34*M,         0),
    (1,         0,          1):      (60*M,         0),
    (1,         1,          1):      (60*M,         0)
    }

#decode_avmem_requirement_table for st5197
decode_avmem_requirement_table_st5197 = {
    #hd_disp    hd_mpeg2    hd_h264  avmem_sys  avmem_vid
    (0,         0,          0):      (6*M,         0)
    }

#platform dependent definition
#include 7100/7109/7101/5201/5203/5202
#only for 29 bits address mode
st7100_spec = {
    'PHYS_RAM_BASE': 0x04000000,
    'OFFSET_FOR_AV_FW': 0x400000,
    'LMI_VID_BASE':0xb0000000,
    'BOARD_MEM_MAP_NAME': 'st71xx_memory_map',
    'BOARD_MEM_LIB_NAME': 'mb411',
    'DECODE_AVMEM_REQUIREMENT_TABLE': decode_avmem_requirement_table_st7100
    }

st7109_spec = {
    'PHYS_RAM_BASE': 0x04000000,
    'OFFSET_FOR_AV_FW': 0x400000,
    'LMI_VID_BASE':0xb0000000,
    'BOARD_MEM_MAP_NAME': 'st71xx_memory_map',
    'BOARD_MEM_LIB_NAME': 'mb411stb7109',
    'DECODE_AVMEM_REQUIREMENT_TABLE': decode_avmem_requirement_table_st7100
    }

st7111_spec = {
    'PHYS_RAM_BASE': 0x0C000000,
    'OFFSET_FOR_AV_FW': 0x800000,
    'LMI_VID_BASE':0,
    'BOARD_MEM_MAP_NAME': 'st71xx_memory_map',
    'BOARD_MEM_LIB_NAME': 'mb618',
    'DECODE_AVMEM_REQUIREMENT_TABLE': decode_avmem_requirement_table_st71xx
    }
st7105_spec = {
    'PHYS_RAM_BASE': 0x0C000000,
    'OFFSET_FOR_AV_FW': 0x600000,
    'LMI_VID_BASE':0,
    'BOARD_MEM_MAP_NAME': 'st71xx_memory_map',
    'BOARD_MEM_LIB_NAME': 'mb680sti7105',
    'DECODE_AVMEM_REQUIREMENT_TABLE': decode_avmem_requirement_table_st71xx
    }
        
st5197_spec = {
    'PHYS_RAM_BASE': 0x0C000000,
    'OFFSET_FOR_AV_FW': 0x000000,
    'LMI_VID_BASE':0,
    'BOARD_MEM_MAP_NAME': 'st71xx_memory_map',
    'BOARD_MEM_LIB_NAME': 'mb704',
    'DECODE_AVMEM_REQUIREMENT_TABLE': decode_avmem_requirement_table_st5197
    }
    
st5206_spec = {
    'PHYS_RAM_BASE': 0x0C000000,
    'OFFSET_FOR_AV_FW': 0x500000,
    'LMI_VID_BASE':0,
    'BOARD_MEM_MAP_NAME': 'st71xx_memory_map',
    'BOARD_MEM_LIB_NAME': 'hdk5289stx5206',
    'DECODE_AVMEM_REQUIREMENT_TABLE': decode_avmem_requirement_table_st71xx
    }



platform_spec = None

validate_mode = False

# min size of System heap&stack
MIN_SYS_HEAP_STACK_SIZE = 2*M

#memory config from input
cfg_in = {
    #hardware config
    'DDR_BUS_NUMBER':1,
    'DDR0_TOTAL_SIZE':0x08000000,
    'DDR1_TOTAL_SIZE':0x00000000,
    #function options
    'HD_DISPLAY_SUPPORT':False,
    'HD_DECODER_SUPPORT':True,
    'HD_H264_SUPPORT':True,
    'PVR_SUPPORT':False,
    'PIP_SUPPORT':False,
    'OSD_BITS_PERPIEXL':32,
    #user defined size
    'SYSTEM_PARTITION_POSITION':0,
    'USER_OSD_AVMEM_SIZE':0x400000
    }

#memory partition define for output
cfg_out = {
    'LMI_SYS_BASE':0,
    'LMI_SYS_SIZE':0,
    'LMI_VID_BASE':0,
    'LMI_VID_SIZE':0,
    'APP_START_ADDR': 0,
    'STACK_ADDR': 0,
    'SYSTEM_PARTITIOAN_START_ADDR': 0,
    'SYSTEM_PARTITIOAN_SIZE': 0,
    'OS_PARTITIOAN_START_ADDR': 0,
    'OS_PARTITIOAN_SIZE': 0,
    'DRIVER_PARTITIOAN_START_ADDR':0,
    'DRIVER_PARTITIOAN_SIZE': 0,
    'NCACHE_PARTITIOAN_START_ADDR':0,
    'NCACHE_PARTITIOAN_SIZE': 0,
    'AVMEM_USER_START_ADDR': 0,
    'AVMEM_USER_SIZE': 0,
    'AVMEM_SYS_START_ADDR':0,
    'AVMEM_SYS_SIZE':0,
    'AVMEM_VID_START_ADDR':0,
    'AVMEM_VID_SIZE':0
    }

#args passed into this script
script_args = {
    'CFG_FILENAME':None,
    'CFG_SECTION':None,
    'MAP_FILENAME':None
    }

#for address translate
def phys_to_cached(addr):
    return long(addr)|0x80000000

def phys_to_uncached(addr):
    return long(addr)|0xA0000000

# workaround for ConfigParser reading HEX
def cfg_get_int(cfg, section, option):
    int_raw = cfg.get(section, option)
    int_s = str(int_raw).strip().lower()
    if int_s[0] == '0' and len(int_s) > 1 and int_s[1] == 'x':
        int_s = int_s.replace('0x', '')
        return int(int_s, 16)
    else:
        return int(int_raw)
        
def read_config():
    logging.debug('read config file...')
    cfg_filename = script_args['CFG_FILENAME']
    cfg_section = script_args['CFG_SECTION']
    
    logging.info('read [%s] from %s' % (cfg_section, cfg_filename))

    # read memory config
    config = ConfigParser.ConfigParser()
    config.read(cfg_filename)

    for k, v in cfg_in.iteritems():
        cfg_in[k] = cfg_get_int(config, cfg_section, k)
        
# do memory partition
def do_memory_partition():

    # TODO params check

    # display buffer size
    bytes_per_pixel = cfg_in['OSD_BITS_PERPIEXL']/8
    if bytes_per_pixel <= 0 or bytes_per_pixel > 4:
        raise Exception('bad value of OSD_BITS_PERPIEXL')
    
    osd_size = 720*576*bytes_per_pixel
    if cfg_in['HD_DISPLAY_SUPPORT']:
        osd_size += 1920*1080*bytes_per_pixel
    elif os.getenv('DVD_BACKEND') != '5197':
