243 lines
5.9 KiB
C
243 lines
5.9 KiB
C
/*
|
|
* Copyright 2017-2018 NXP
|
|
*
|
|
* 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.
|
|
*/
|
|
#ifndef _IMX_HDP_H_
|
|
#define _IMX_HDP_H_
|
|
|
|
#include <linux/regmap.h>
|
|
#include <linux/mutex.h>
|
|
#include <drm/drm_of.h>
|
|
#include <drm/drmP.h>
|
|
#include <drm/drm_atomic_helper.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_edid.h>
|
|
#include <drm/drm_encoder_slave.h>
|
|
#include <drm/drm_atomic.h>
|
|
#include <soc/imx8/sc/sci.h>
|
|
|
|
#include <drm/drm_dp_helper.h>
|
|
#include "../../../../mxc/hdp/all.h"
|
|
#include "../../../../mxc/hdp-cec/imx-hdp-cec.h"
|
|
|
|
/* For testing hdp firmware define DEBUG_FW_LOAD */
|
|
#undef DEBUG_FW_LOAD
|
|
#define PLL_1188MHZ (1188000000)
|
|
#define PLL_675MHZ (675000000)
|
|
|
|
#define HDP_TX_SS_LIS_BASE 0x0000
|
|
#define HDP_TX_SS_CSR_BASE 0x1000
|
|
#define HDP_TX_SS_GPIO_BASE 0x2000
|
|
#define HDP_TX_SS_CTRL0_BASE 0x8000
|
|
|
|
#define CSR_PIXEL_LINK_MUX_CTL 0x00
|
|
#define PL_MUX_CTL_VCP_OFFSET 5
|
|
#define PL_MUX_CTL_HCP_OFFSET 4
|
|
#define PL_MUX_CTL_PL_MUX_OFFSET 2
|
|
#define PL_MUX_CTL_PL_SEL_OFFSET 0
|
|
|
|
#define CSR_PIXEL_LINK_MUX_STATUS 0x04
|
|
#define PL_MUX_STATUS_PL1_INT_OFFSET 18
|
|
#define PL_MUX_STATUS_PL1_ADD_OFFSET 16
|
|
#define PL_MUX_STATUS_PL1_TYP_OFFSET 11
|
|
#define PL_MUX_STATUS_PL0_INT_OFFSET 9
|
|
#define PL_MUX_STATUS_PL0_ADD_OFFSET 7
|
|
#define PL_MUX_STATUS_PL0_TYP_OFFSET 2
|
|
#define PL_MUX_STATUS_PL_DLY_OFFSET 0
|
|
|
|
#define CSR_HDP_TX_CTRL_CTRL0 0x08
|
|
#define CSR_HDP_TX_CTRL_CTRL1 0x0c
|
|
|
|
#define HOTPLUG_DEBOUNCE_MS 200
|
|
|
|
#define VIC_MODE_97_60Hz 97
|
|
/**
|
|
* imx_hdp_call - Calls a struct imx hdp_operations operation on
|
|
* an entity
|
|
*
|
|
* @entity: entity where the @operation will be called
|
|
* @operation: type of the operation. Should be the name of a member of
|
|
* struct &media_entity_operations.
|
|
*
|
|
* This helper function will check if @operation is not %NULL. On such case,
|
|
* it will issue a call to @operation\(@args\).
|
|
*/
|
|
|
|
#define imx_hdp_call(hdp, operation, args...) \
|
|
(!(hdp) ? -ENODEV : (((hdp)->ops && (hdp)->ops->operation) ? \
|
|
(hdp)->ops->operation(args) : ENOIOCTLCMD))
|
|
|
|
#define clks_to_imx_hdp(env) \
|
|
container_of(env, struct imx_hdp, clks)
|
|
|
|
#define state_to_imx_hdp(env) \
|
|
container_of(env, struct imx_hdp, state)
|
|
|
|
struct hdp_clks;
|
|
|
|
struct hdp_ops {
|
|
void (*fw_load)(state_struct *state);
|
|
int (*fw_init)(state_struct *state);
|
|
int (*phy_init)(state_struct *state, struct drm_display_mode *mode, int format, int color_depth);
|
|
void (*mode_set)(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int max_link);
|
|
int (*get_edid_block)(void *data, u8 *buf, u32 block, size_t len);
|
|
int (*get_hpd_state)(state_struct *state, u8 *hpd);
|
|
int (*write_hdr_metadata)(state_struct *state,
|
|
union hdmi_infoframe *hdr_infoframe);
|
|
|
|
void (*phy_reset)(sc_ipc_t ipcHndl, u8 reset);
|
|
int (*pixel_link_init)(state_struct *state);
|
|
void (*pixel_link_deinit)(state_struct *state);
|
|
void (*pixel_link_mux)(state_struct *state, struct drm_display_mode *mode);
|
|
|
|
int (*clock_init)(struct hdp_clks *clks);
|
|
int (*ipg_clock_enable)(struct hdp_clks *clks);
|
|
void (*ipg_clock_disable)(struct hdp_clks *clks);
|
|
void (*ipg_clock_set_rate)(struct hdp_clks *clks);
|
|
int (*pixel_clock_enable)(struct hdp_clks *clks);
|
|
void (*pixel_clock_disable)(struct hdp_clks *clks);
|
|
void (*pixel_clock_set_rate)(struct hdp_clks *clks);
|
|
};
|
|
|
|
struct hdp_devtype {
|
|
u8 is_edid;
|
|
u8 is_4kp60;
|
|
u8 audio_type;
|
|
struct hdp_ops *ops;
|
|
struct hdp_rw_func *rw;
|
|
};
|
|
|
|
struct hdp_video {
|
|
u32 bpp;
|
|
u32 format;
|
|
u32 lanes;
|
|
u32 color_type; /* bt */
|
|
u32 color_depth; /* bpc */
|
|
struct drm_display_mode cur_mode;
|
|
struct drm_display_mode pre_mode;
|
|
void __iomem *regs_base;
|
|
};
|
|
|
|
struct hdp_audio {
|
|
u32 interface; /* I2S SPDIF */
|
|
u32 freq;
|
|
u32 nlanes;
|
|
u32 nChannels;
|
|
u32 sample_width;
|
|
u32 sample_rate;
|
|
u32 audio_cts;
|
|
u32 audio_n;
|
|
bool audio_enable;
|
|
spinlock_t audio_lock;
|
|
struct mutex audio_mutex;
|
|
void __iomem *regs_base;
|
|
};
|
|
|
|
struct hdp_hdcp {
|
|
void __iomem *regs_base;
|
|
};
|
|
|
|
struct hdp_phy {
|
|
u32 index;
|
|
u32 number;
|
|
bool enabled;
|
|
struct phy *phy;
|
|
void __iomem *regs_base;
|
|
};
|
|
|
|
struct hdp_clks {
|
|
struct clk *av_pll;
|
|
struct clk *dig_pll;
|
|
struct clk *clk_ipg;
|
|
struct clk *clk_core;
|
|
struct clk *clk_pxl;
|
|
struct clk *clk_pxl_mux;
|
|
struct clk *clk_pxl_link;
|
|
|
|
struct clk *clk_hdp;
|
|
struct clk *clk_phy;
|
|
struct clk *clk_apb;
|
|
|
|
struct clk *clk_lis;
|
|
struct clk *clk_msi;
|
|
struct clk *clk_lpcg;
|
|
struct clk *clk_even;
|
|
struct clk *clk_dbl;
|
|
struct clk *clk_vif;
|
|
struct clk *clk_apb_csr;
|
|
struct clk *clk_apb_ctrl;
|
|
struct clk *av_pll_div;
|
|
struct clk *dig_pll_div;
|
|
struct clk *clk_i2s;
|
|
struct clk *clk_i2s_bypass;
|
|
};
|
|
|
|
enum hdp_tx_irq {
|
|
HPD_IRQ_IN,
|
|
HPD_IRQ_OUT,
|
|
HPD_IRQ_NUM,
|
|
};
|
|
|
|
struct imx_hdp {
|
|
struct device *dev;
|
|
struct drm_connector connector;
|
|
struct drm_encoder encoder;
|
|
struct drm_bridge bridge;
|
|
|
|
struct edid *edid;
|
|
char cable_state;
|
|
|
|
struct hdp_mem mem;
|
|
|
|
u8 is_edid;
|
|
u8 is_4kp60;
|
|
u8 is_cec;
|
|
u8 audio_type;
|
|
|
|
struct mutex mutex; /* for state below and previous_mode */
|
|
enum drm_connector_force force; /* mutex-protected force state */
|
|
|
|
struct hdp_video video;
|
|
|
|
struct drm_dp_aux aux;
|
|
struct mutex aux_mutex;
|
|
|
|
struct drm_dp_link dp_link;
|
|
S_LINK_STAT lkstat;
|
|
ENUM_AFE_LINK_RATE link_rate;
|
|
|
|
sc_ipc_t ipcHndl;
|
|
u32 mu_id;
|
|
u32 dual_mode;
|
|
struct hdp_ops *ops;
|
|
struct hdp_rw_func *rw;
|
|
struct hdp_clks clks;
|
|
state_struct state;
|
|
int vic;
|
|
int irq[HPD_IRQ_NUM];
|
|
struct delayed_work hotplug_work;
|
|
|
|
struct imx_cec_dev cec;
|
|
|
|
int bpc;
|
|
VIC_PXL_ENCODING_FORMAT format;
|
|
bool hdr_metadata_present;
|
|
bool hdr_mode;
|
|
};
|
|
|
|
void imx_hdp_register_audio_driver(struct device *dev);
|
|
void imx_arc_power_up(state_struct *state);
|
|
void imx_arc_calibrate(state_struct *state);
|
|
void imx_arc_config(state_struct *state);
|
|
|
|
#endif
|