Merge commit 'ce6e1b95ba555d78ea1f4ca5653a1c8a074c1745'

* commit 'ce6e1b95ba555d78ea1f4ca5653a1c8a074c1745':
  arm64: dts: rockchip: rk3576-android: enabled wdt
  usb: typec: tcpci_husb311: Disable IRQ before unregistering TCPCI port
  misc: rk628: hdmitx: supplement valid modes
  misc: rk628: bt1120rx: rk628d adjust cpll frequency to support more frequencies
  misc: rk628: bt1120rx: rk628f adjust cpll frequency to support more frequencies
  misc: rk628: cru: clock adjustment logic optimization
  misc: rk628: cru: add clk_summary for debugging
  misc: rk628: hdmitx: fix rk628d display anomaly when clock frequency is below 40MHz
  phy: rockchip: inno-usb2: Add refclock freq setting
  media: rockchip: vpss: fix offline device id out of range
  phy: rockchip: usbdp: amend ssc modulation deviation
  media: i2c: lontium driver: remove judge timing valid
  drm/rockchip: analogix_dp: fix the log to indicate edp data source
  video: rockchip: mpp: rk3576: fix enc err when rec_fbc_dis=1
  media: rockchip: vpss: offline support 8k
  drm/rockchip: dw-hdmi-qp: Enable/disable hdcp without hdmi enable/disable
  arm64: dts: rockchip: rk3576: fix apb clk to PCLK_HDPTX_APB for edp
  media: rockchip: hdmirx: fix low_latency NULL pointer err.
  ASoC: es8323: add support 'ADC Data Select' control node

Change-Id: I3c5237b5d3c98957a1d02b563ea8ee5c1e3d45b6
This commit is contained in:
Tao Huang
2024-06-14 20:00:32 +08:00
25 changed files with 1558 additions and 506 deletions

View File

@@ -81,3 +81,7 @@
&vop {
support-multi-area;
};
&wdt {
status= "okay";
};

View File

@@ -5186,7 +5186,7 @@
hdptxphy: phy@2b000000 {
compatible = "rockchip,rk3576-hdptx-phy", "rockchip,rk3588-hdptx-phy";
reg = <0x0 0x2b000000 0x0 0x2000>;
clocks = <&cru CLK_PHY_REF_SRC>, <&cru PCLK_PMUPHY_ROOT>;
clocks = <&cru CLK_PHY_REF_SRC>, <&cru PCLK_HDPTX_APB>;
clock-names = "ref", "apb";
resets = <&cru SRST_P_HDPTX_APB>, <&cru SRST_HDPTX_INIT>,
<&cru SRST_HDPTX_CMN>, <&cru SRST_HDPTX_LANE>;

View File

@@ -2075,9 +2075,8 @@ static u8 dw_hdmi_qp_hdcp_capable(struct dw_hdmi_qp *hdmi)
}
static void dw_hdmi_qp_hdcp_enable(struct dw_hdmi_qp *hdmi,
struct drm_connector *connector)
const struct drm_connector_state *conn_state)
{
const struct drm_connector_state *conn_state = connector->state;
void *data = hdmi->plat_data->phy_data;
hdmi_writel(hdmi, 0, HDCP2LOGIC_ESM_GPIO_IN);
@@ -2715,8 +2714,31 @@ static bool check_hdr_color_change(struct drm_connector_state *old_state,
return false;
}
static bool check_dw_hdcp_state_changed(struct drm_connector *conn,
struct drm_atomic_state *state)
static void dw_hdmi_qp_hdcp_disable(struct dw_hdmi_qp *hdmi,
const struct drm_connector_state *conn_state)
{
void *data = hdmi->plat_data->phy_data;
hdmi_writel(hdmi, 0, AVP_1_INT_MASK_N);
hdmi_writel(hdmi, 0, AVP_3_INT_MASK_N);
if (hdmi->hdcp && hdmi->hdcp->hdcp_stop)
hdmi->hdcp->hdcp_stop(hdmi->hdcp);
hdmi_writel(hdmi, 0x34, HDCP2LOGIC_ESM_GPIO_IN);
hdmi_modb(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
if (conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
drm_hdcp_update_content_protection(hdmi->curr_conn,
DRM_MODE_CONTENT_PROTECTION_DESIRED);
hdmi->hdcp_status = 0;
if (hdmi->plat_data->set_hdcp_status)
hdmi->plat_data->set_hdcp_status(data, hdmi->hdcp_status);
}
static void set_dw_hdmi_hdcp_enable(struct dw_hdmi_qp *hdmi,
struct drm_connector *conn,
struct drm_atomic_state *state)
{
struct drm_connector_state *old_state, *new_state;
u64 old_cp, new_cp;
@@ -2726,24 +2748,14 @@ static bool check_dw_hdcp_state_changed(struct drm_connector *conn,
old_cp = old_state->content_protection;
new_cp = new_state->content_protection;
if (old_state->hdcp_content_type != new_state->hdcp_content_type &&
new_cp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
new_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
return true;
if (old_cp != new_cp) {
if (new_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
old_cp == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
dw_hdmi_qp_hdcp_enable(hdmi, new_state);
else if (new_cp == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED)
dw_hdmi_qp_hdcp_disable(hdmi, new_state);
}
if (!new_state->crtc) {
if (old_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
new_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
return false;
}
if (old_cp == new_cp ||
(old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
return false;
return true;
}
static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
@@ -2890,9 +2902,6 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
}
}
if (check_dw_hdcp_state_changed(connector, state))
crtc_state->mode_changed = true;
return 0;
}
@@ -2908,6 +2917,8 @@ static void dw_hdmi_connector_atomic_commit(struct drm_connector *connector,
hdmi_writel(hdmi, 2, PKTSCHED_PKT_CONTROL0);
hdmi->update = false;
}
set_dw_hdmi_hdcp_enable(hdmi, connector, state);
}
void dw_hdmi_qp_set_output_type(struct dw_hdmi_qp *hdmi, u64 val)
@@ -3078,21 +3089,7 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
hdmi_writel(hdmi, 1, PKTSCHED_PKT_CONTROL0);
mdelay(50);
hdmi_writel(hdmi, 0, AVP_1_INT_MASK_N);
hdmi_writel(hdmi, 0, AVP_3_INT_MASK_N);
if (hdmi->hdcp && hdmi->hdcp->hdcp_stop)
hdmi->hdcp->hdcp_stop(hdmi->hdcp);
hdmi_writel(hdmi, 0x34, HDCP2LOGIC_ESM_GPIO_IN);
hdmi_modb(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
if (conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
drm_hdcp_update_content_protection(hdmi->curr_conn,
DRM_MODE_CONTENT_PROTECTION_DESIRED);
hdmi->hdcp_status = 0;
if (hdmi->plat_data->set_hdcp_status)
hdmi->plat_data->set_hdcp_status(data, hdmi->hdcp_status);
dw_hdmi_qp_hdcp_disable(hdmi, conn_state);
extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false);
handle_plugged_change(hdmi, false);
@@ -3165,7 +3162,7 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
if (hdmi->panel)
drm_panel_enable(hdmi->panel);
dw_hdmi_qp_hdcp_enable(hdmi, hdmi->curr_conn);
dw_hdmi_qp_hdcp_enable(hdmi, hdmi->curr_conn->state);
}
static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {

View File

@@ -383,6 +383,9 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
struct rockchip_dp_device *dp = encoder_to_dp(encoder);
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
struct of_endpoint endpoint;
struct device_node *remote_port_parent;
char name[32];
int ret;
crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
@@ -398,11 +401,21 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
if (ret != 0)
DRM_DEV_ERROR(dp->dev, "Could not write to GRF reg mem_clk_auto_gating: %d\n", ret);
ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
ret = drm_of_encoder_active_endpoint(dp->dev->of_node, encoder, &endpoint);
if (ret < 0)
return;
DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
remote_port_parent = of_graph_get_remote_port_parent(endpoint.local_node);
if (remote_port_parent) {
if (of_get_child_by_name(remote_port_parent, "ports"))
sprintf(name, "%s vp%d", remote_port_parent->full_name, endpoint.id);
else
sprintf(name, "%s %s",
remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
of_node_put(remote_port_parent);
DRM_DEV_DEBUG(dp->dev, "%s output to edp\n", name);
}
ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
if (ret != 0)

View File

@@ -739,12 +739,6 @@ static int lt6911uxc_s_dv_timings(struct v4l2_subdev *sd,
return 0;
}
if (!v4l2_valid_dv_timings(timings,
&lt6911uxc_timings_cap, NULL, NULL)) {
v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);
return -ERANGE;
}
lt6911uxc->timings = *timings;
enable_stream(sd, false);

View File

@@ -654,12 +654,6 @@ static int lt7911d_s_dv_timings(struct v4l2_subdev *sd,
return 0;
}
if (!v4l2_valid_dv_timings(timings,
&lt7911d_timings_cap, NULL, NULL)) {
v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);
return -ERANGE;
}
lt7911d->timings = *timings;
enable_stream(sd, false);

View File

@@ -925,12 +925,6 @@ static int lt7911uxc_s_dv_timings(struct v4l2_subdev *sd,
return 0;
}
if (!v4l2_valid_dv_timings(timings,
&lt7911uxc_timings_cap, NULL, NULL)) {
v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);
return -ERANGE;
}
lt7911uxc->timings = *timings;
enable_stream(sd, false);

View File

@@ -892,12 +892,6 @@ static int lt8668sx_s_dv_timings(struct v4l2_subdev *sd,
return 0;
}
if (!v4l2_valid_dv_timings(timings,
&lt8668sx_timings_cap, NULL, NULL)) {
v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);
return -ERANGE;
}
lt8668sx->timings = *timings;
lt8668sx->last_framerate = lt8668sx->cur_framerate;

View File

@@ -2195,6 +2195,7 @@ static void hdmirx_free_fence(struct rk_hdmirx_dev *hdmirx_dev)
unsigned long lock_flags = 0;
struct hdmirx_fence *vb_fence, *done_fence;
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
struct files_struct *files = current->files;
LIST_HEAD(local_list);
spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
@@ -2216,7 +2217,8 @@ static void hdmirx_free_fence(struct rk_hdmirx_dev *hdmirx_dev)
v4l2_dbg(2, debug, v4l2_dev, "%s: free qbuf_fence fd:%d\n",
__func__, vb_fence->fence_fd);
dma_fence_put(vb_fence->fence);
put_unused_fd(vb_fence->fence_fd);
if (files)
put_unused_fd(vb_fence->fence_fd);
kfree(vb_fence);
}
@@ -2229,7 +2231,8 @@ static void hdmirx_free_fence(struct rk_hdmirx_dev *hdmirx_dev)
v4l2_dbg(2, debug, v4l2_dev, "%s: free done_fence fd:%d\n",
__func__, done_fence->fence_fd);
dma_fence_put(done_fence->fence);
put_unused_fd(done_fence->fence_fd);
if (files)
put_unused_fd(done_fence->fence_fd);
kfree(done_fence);
}
}

View File

@@ -20,11 +20,12 @@
#define RKVPSS_DEFAULT_WIDTH 1920
#define RKVPSS_DEFAULT_HEIGHT 1080
#define RKVPSS_MAX_WIDTH 4672
#define RKVPSS_MAX_HEIGHT 3504
#define RKVPSS_MIN_WIDTH 32
#define RKVPSS_MIN_HEIGHT 32
#define RKVPSS_UNITE_MAX_WIDTH 8192
#define RKVPSS_UNITE_MAX_HEIGHT 6144
#define RKVPSS_VIDEO_NAME_LEN 16
#define RKVPSS_REG_CACHE_SYNC 0xeeeeeeee
@@ -43,6 +44,13 @@ enum rkvpss_fmt_pix_type {
FMT_RGB,
};
enum rkvpss_rotate {
ROTATE_0 = 0,
ROTATE_90,
ROTATE_180,
ROTATE_270,
};
/* One structure per video node */
struct rkvpss_vdev_node {
struct vb2_queue buf_queue;

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,9 @@
#ifndef _RKVPSS_OFFLINE_H
#define _RKVPSS_OFFLINE_H
#define DEV_NUM_MAX 10
#define DEV_NUM_MAX 256
#define UNITE_ENLARGE 16
#define UNITE_LEFT_ENLARGE 16
#include "hw.h"
@@ -45,6 +47,20 @@ struct rkvpss_dev_rate {
u32 delay;
};
struct rkvpss_unite_scl_params {
u32 y_w_fac;
u32 c_w_fac;
u32 y_h_fac;
u32 c_h_fac;
u32 y_w_phase;
u32 c_w_phase;
u32 quad_crop_w;
u32 scl_in_crop_w_y;
u32 scl_in_crop_w_c;
u32 right_scl_need_size_y;
u32 right_scl_need_size_c;
};
struct rkvpss_offline_dev {
struct rkvpss_hw_dev *hw;
struct v4l2_device v4l2_dev;
@@ -56,6 +72,8 @@ struct rkvpss_offline_dev {
struct list_head cfginfo_list;
struct mutex ofl_lock;
struct rkvpss_dev_rate dev_rate[DEV_NUM_MAX];
struct rkvpss_unite_scl_params unite_params[RKVPSS_OUTPUT_MAX];
u32 unite_right_enlarge;
bool mode_sel_en;
};

View File

@@ -1321,6 +1321,7 @@ static void rk628_debugfs_create(struct rk628 *rk628)
rk628_debugfs_register_create(rk628);
rk628_cru_create_debugfs_file(rk628);
rk628_rgb_decoder_create_debugfs_file(rk628);
rk628_post_process_create_debugfs_file(rk628);
rk628_mipi_dsi_create_debugfs_file(rk628);

View File

@@ -5,6 +5,8 @@
* Author: Wyon Bi <bivvy.bi@rock-chips.com>
*/
#include <linux/debugfs.h>
#include "asm-generic/errno-base.h"
#include "rk628.h"
#include "rk628_cru.h"
@@ -273,19 +275,85 @@ static unsigned long rk628_cru_clk_set_rate_pll(struct rk628 *rk628,
return (unsigned long)foutpostdiv;
}
static int rk628_cru_clk_get_parent_rate(struct rk628 *rk628, unsigned int id,
unsigned int *parent_id,
unsigned long *parent_rate)
{
u32 val;
int parent = -1;
switch (id) {
case CGU_CLK_RX_READ:
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
val &= CLK_RX_READ_SEL_MASK;
val >>= CLK_RX_READ_SEL_SHIFT;
parent = val == CLK_RX_READ_SEL_GPLL ? CGU_CLK_GPLL : CGU_CLK_CPLL;
break;
case CGU_SCLK_VOP:
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
val &= CLK_UART_SRC_SEL_MASK;
val >>= SCLK_VOP_SEL_SHIFT;
parent = val == SCLK_VOP_SEL_GPLL ? CGU_CLK_GPLL : CGU_CLK_CPLL;
break;
case CGU_CLK_UART_SRC:
rk628_i2c_read(rk628, CRU_CLKSEL_CON21, &val);
val &= SCLK_VOP_SEL_MASK;
parent = val == CLK_UART_SRC_SEL_GPLL ? CGU_CLK_GPLL : CGU_CLK_CPLL;
break;
case CGU_BT1120DEC:
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
val &= CLK_BT1120DEC_SEL_MASK;
parent = val == CLK_BT1120DEC_SEL_GPLL ? CGU_CLK_GPLL : CGU_CLK_CPLL;
break;
case CGU_CLK_HDMIRX_AUD:
rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &val);
if (rk628->version >= RK628F_VERSION)
val = (val & CLK_HDMIRX_AUD_SEL_MASK_V2) >> 14;
else
val = (val & CLK_HDMIRX_AUD_SEL_MASK_V1) >> 15;
switch (val) {
case 0:
parent = CGU_CLK_CPLL;
break;
case 1:
parent = CGU_CLK_GPLL;
break;
case 2:
parent = CGU_CLK_APLL;
}
break;
case CGU_CLK_IMODET:
rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &val);
val &= CLK_IMODET_SEL_MASK;
val >>= CLK_IMODET_SEL_SHIFT;
parent = val == SCLK_VOP_SEL_GPLL ? CGU_CLK_GPLL : CGU_CLK_CPLL;
break;
default:
return -EINVAL;
}
if (parent < 0)
return -EINVAL;
if (parent_id)
*parent_id = parent;
if (parent_rate)
*parent_rate = rk628_cru_clk_get_rate(rk628, parent);
return 0;
}
static unsigned long rk628_cru_clk_set_rate_sclk_vop(struct rk628 *rk628,
unsigned long rate)
{
unsigned long m, n, parent_rate;
u32 val;
int ret;
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
val &= SCLK_VOP_SEL_MASK;
val >>= SCLK_VOP_SEL_SHIFT;
if (val == SCLK_VOP_SEL_GPLL)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_SCLK_VOP,
NULL, &parent_rate);
if (ret)
return 0;
rational_best_approximation(rate, parent_rate,
GENMASK(15, 0), GENMASK(15, 0),
@@ -298,15 +366,13 @@ static unsigned long rk628_cru_clk_set_rate_sclk_vop(struct rk628 *rk628,
static unsigned long rk628_cru_clk_get_rate_sclk_vop(struct rk628 *rk628)
{
unsigned long rate, parent_rate, m, n;
u32 mux, div;
u32 div;
int ret;
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &mux);
mux &= CLK_UART_SRC_SEL_MASK;
mux >>= SCLK_VOP_SEL_SHIFT;
if (mux == SCLK_VOP_SEL_GPLL)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_SCLK_VOP,
NULL, &parent_rate);
if (ret)
return 0;
rk628_i2c_read(rk628, CRU_CLKSEL_CON13, &div);
m = div >> 16 & 0xffff;
@@ -319,15 +385,13 @@ static unsigned long rk628_cru_clk_get_rate_sclk_vop(struct rk628 *rk628)
static unsigned long rk628_cru_clk_get_rate_clk_imodet(struct rk628 *rk628)
{
unsigned long rate, parent_rate, n;
u32 mux, div;
u32 div;
int ret;
rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &mux);
mux &= CLK_IMODET_SEL_MASK;
mux >>= CLK_IMODET_SEL_SHIFT;
if (mux == SCLK_VOP_SEL_GPLL)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_CLK_IMODET,
NULL, &parent_rate);
if (ret)
return 0;
rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &div);
n = div & 0x1f;
@@ -340,15 +404,12 @@ static unsigned long rk628_cru_clk_set_rate_rx_read(struct rk628 *rk628,
unsigned long rate)
{
unsigned long m, n, parent_rate;
u32 val;
int ret;
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
val &= CLK_RX_READ_SEL_MASK;
val >>= CLK_RX_READ_SEL_SHIFT;
if (val == CLK_RX_READ_SEL_GPLL)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_CLK_RX_READ,
NULL, &parent_rate);
if (ret)
return 0;
rational_best_approximation(rate, parent_rate,
GENMASK(15, 0), GENMASK(15, 0),
@@ -358,17 +419,35 @@ static unsigned long rk628_cru_clk_set_rate_rx_read(struct rk628 *rk628,
return rate;
}
static unsigned long rk628_cru_clk_get_rate_rx_read(struct rk628 *rk628)
{
unsigned long rate, m, n, parent_rate;
u32 div;
int ret;
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_CLK_RX_READ,
NULL, &parent_rate);
if (ret)
return 0;
rk628_i2c_read(rk628, CRU_CLKSEL_CON14, &div);
m = div >> 16 & 0xffff;
n = div & 0xffff;
rate = parent_rate * m / n;
return rate;
}
static unsigned long rk628_cru_clk_get_rate_uart_src(struct rk628 *rk628)
{
unsigned long rate, parent_rate;
u32 mux, div;
u32 div;
int ret;
rk628_i2c_read(rk628, CRU_CLKSEL_CON21, &mux);
mux &= SCLK_VOP_SEL_MASK;
if (mux == CLK_UART_SRC_SEL_GPLL)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_CLK_UART_SRC,
NULL, &parent_rate);
if (ret)
return 0;
rk628_i2c_read(rk628, CRU_CLKSEL_CON21, &div);
div &= CLK_UART_SRC_DIV_MASK;
@@ -429,51 +508,34 @@ static unsigned long rk628_cru_clk_set_rate_sclk_hdmirx_aud(struct rk628 *rk628,
static unsigned long rk628_cru_clk_get_rate_sclk_hdmirx_aud(struct rk628 *rk628)
{
unsigned long rate;
u64 parent_rate;
u8 div;
u32 val;
unsigned long rate, parent_rate;
u32 div;
int ret;
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_CLK_HDMIRX_AUD,
NULL, &parent_rate);
if (ret)
return 0;
rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &div);
div = ((div & CLK_HDMIRX_AUD_DIV_MASK) >> 6) + 1;
rate = parent_rate / div;
rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &val);
div = ((val & CLK_HDMIRX_AUD_DIV_MASK) >> 6) + 1;
if (rk628->version >= RK628F_VERSION)
val = (val & CLK_HDMIRX_AUD_SEL_MASK_V2) >> 14;
else
val = (val & CLK_HDMIRX_AUD_SEL_MASK_V1) >> 15;
if (!val)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
else if (val == 2)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_APLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
do_div(parent_rate, div);
rate = parent_rate;
return rate;
}
static unsigned long
rk628_cru_clk_get_rate_bt1120_dec_parent(struct rk628 *rk628)
{
unsigned long parent_rate;
u32 mux;
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &mux);
mux &= CLK_BT1120DEC_SEL_MASK;
if (mux == CLK_BT1120DEC_SEL_GPLL)
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
else
parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
return parent_rate;
}
static unsigned long rk628_cru_clk_set_rate_bt1120_dec(struct rk628 *rk628,
unsigned long rate)
{
unsigned long parent_rate;
u32 div;
int ret;
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_BT1120DEC,
NULL, &parent_rate);
if (ret)
return 0;
parent_rate = rk628_cru_clk_get_rate_bt1120_dec_parent(rk628);
div = DIV_ROUND_UP(parent_rate, rate);
rk628_i2c_write(rk628, CRU_CLKSEL_CON02, CLK_BT1120DEC_DIV(div-1));
@@ -484,8 +546,12 @@ static unsigned long rk628_cru_clk_get_rate_bt1120_dec(struct rk628 *rk628)
{
unsigned long parent_rate;
u32 div;
int ret;
parent_rate = rk628_cru_clk_get_rate_bt1120_dec_parent(rk628);
ret = rk628_cru_clk_get_parent_rate(rk628, CGU_BT1120DEC,
NULL, &parent_rate);
if (ret)
return 0;
rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &div);
div = (div & 0x1f) + 1;
@@ -540,6 +606,9 @@ unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id)
case CGU_CLK_GPLL:
rate = rk628_cru_clk_get_rate_pll(rk628, id);
break;
case CGU_CLK_RX_READ:
rate = rk628_cru_clk_get_rate_rx_read(rk628);
break;
case CGU_SCLK_VOP:
rate = rk628_cru_clk_get_rate_sclk_vop(rk628);
break;
@@ -559,32 +628,201 @@ unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id)
return rate;
}
static void rk628_cru_show_pll_tree(struct seq_file *s, unsigned int parent_id,
const char *parent_name)
{
struct rk628 *rk628 = s->private;
unsigned long rate;
unsigned int parent, i;
unsigned int id_list[] = {
CGU_CLK_RX_READ,
CGU_SCLK_VOP,
CGU_BT1120DEC,
CGU_CLK_HDMIRX_AUD,
CGU_CLK_IMODET
};
char const *id_name[] = {
"clk_rx_read",
"clk_sclk_vop",
"clk_bt1120dec",
"clk_hdmirx_aud",
"clk_imodet"
};
if (rk628->version < RK628F_VERSION && parent_id == CGU_CLK_APLL)
return;
rate = rk628_cru_clk_get_rate(rk628, parent_id);
seq_printf(s, "%-22s %10lu\n", parent_name, rate);
for (i = 0; i < ARRAY_SIZE(id_list); ++i) {
rk628_cru_clk_get_parent_rate(rk628, id_list[i], &parent, NULL);
if (parent != parent_id)
continue;
rate = rk628_cru_clk_get_rate(rk628, id_list[i]);
seq_printf(s, " %-18s %10lu\n", id_name[i], rate);
}
}
static int rk628_cru_show_clk_tree(struct seq_file *s, void *data)
{
unsigned int pll_list[] = {CGU_CLK_CPLL, CGU_CLK_GPLL, CGU_CLK_APLL};
char const *pll_name[] = {"cpll", "gpll", "apll"};
unsigned int i;
seq_printf(s, "%-22s %10s\n", " clock", "rate ");
seq_puts(s, "---------------------------------\n");
for (i = 0; i < ARRAY_SIZE(pll_list); ++i)
rk628_cru_show_pll_tree(s, pll_list[i], pll_name[i]);
return 0;
}
static int rk628_clk_summary_open(struct inode *inode, struct file *file)
{
struct rk628 *rk628 = inode->i_private;
return single_open(file, rk628_cru_show_clk_tree, rk628);
}
static const struct file_operations rk628_clk_summary_fops = {
.owner = THIS_MODULE,
.open = rk628_clk_summary_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
void rk628_cru_create_debugfs_file(struct rk628 *rk628)
{
debugfs_create_file("clk_summary", 0400, rk628->debug_dir, rk628,
&rk628_clk_summary_fops);
}
void rk628_cru_init(struct rk628 *rk628)
{
u32 val;
u8 mcu_mode;
/*
* In rk628d application, if you need to dynamically tune the cpll
* frequency, you need to mount pclk under gpll, otherwise it will
* affect the i2c use. The bt1120rx only supports 5bit integer crossover
* frequency, in order to crossover frequency accurately, you need to
* adjust the cpll frequency dynamically, so in the scenario of rk628d
* bt1120rx, mount the pclk under gpll.
*/
rk628_i2c_read(rk628, GRF_SYSTEM_STATUS0, &val);
mcu_mode = (val & I2C_ONLY_FLAG) ? 0 : 1;
if (mcu_mode || rk628->version >= RK628F_VERSION) {
rk628_i2c_write(rk628, CRU_MODE_CON00, HIWORD_UPDATE(1, 4, 4));
/*
* rk628d pclk use cpll by default, and frequency is 99MHz
* rk628f pclk use gpll by default, and frequency is 98.304MHz
*/
if (rk628_input_is_bt1120(rk628)) {
/* set pclk use gpll, and set pclk 98.304Hz */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0089);
}
return;
}
/* clock switch and first set gpll almost 99MHz */
rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff701d);
mdelay(1);
/* set clk_gpll_mux from gpll */
rk628_i2c_write(rk628, CRU_MODE_CON00, 0xffff0004);
mdelay(1);
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0080);
/* set pclk use gpll, now div is 4 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0083);
/* set cpll almost 400MHz */
rk628_i2c_write(rk628, CRU_CPLL_CON0, 0xffff3063);
mdelay(1);
/* set clk_cpll_mux from clk_cpll */
rk628_i2c_write(rk628, CRU_MODE_CON00, 0xffff0005);
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0003);
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff000b);
rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff1028);
mdelay(1);
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff008b);
rk628_i2c_write(rk628, CRU_CPLL_CON0, 0xffff1063);
mdelay(1);
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff000b);
if (rk628_input_is_bt1120(rk628)) {
/* set pclk use cpll, now div is 4 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0003);
/* set pclk use cpll, now div is 10 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0009);
/* set gpll 983.04Hz */
rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff1028);
mdelay(1);
/* set pclk use gpll, now div is 10 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0089);
/* set cpll 1188MHz */
rk628_i2c_write(rk628, CRU_CPLL_CON0, 0xffff1063);
/* final: cpll 1188MHz, gpll 983.04Hz, pclk (use gpll) 98.304Hz */
} else {
/* set pclk use cpll, now div is 4 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0003);
/* set pclk use cpll, now div is 12 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff000b);
/* set gpll 983.04Hz */
rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff1028);
mdelay(1);
/* set pclk use gpll, now div is 12 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff008b);
/* set cpll 1188MHz */
rk628_i2c_write(rk628, CRU_CPLL_CON0, 0xffff1063);
mdelay(1);
/* set pclk use cpll, now div is 12 */
rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff000b);
/* final: cpll 1188MHz, gpll 983.04Hz, pclk (use cpll) 99Hz */
}
}
void rk628_cru_clk_adjust(struct rk628 *rk628)
{
struct rk628_display_mode *src = &rk628->src_mode;
const struct rk628_display_mode *dst = &rk628->dst_mode;
u64 dst_rate, src_rate;
unsigned long dec_clk_rate;
u32 val;
/*
* Try to keep cpll frequency close to 1188m (Tested bt1120rx and rk628f
* hdmirx scenarios)
*/
if ((rk628_input_is_hdmi(rk628) && rk628->version != RK628D_VERSION) ||
rk628_input_is_bt1120(rk628)) {
val = 1188000000UL / (src->clock * 1000);
if (rk628_input_is_bt1120(rk628) && val > (CLK_BT1120DEC_DIV_MAX + 1))
val = CLK_BT1120DEC_DIV_MAX + 1;
val *= src->clock * 1000;
rk628_cru_clk_set_rate(rk628, CGU_CLK_CPLL, val);
msleep(50);
dev_info(rk628->dev, "adjust cpll to %uHz", val);
}
/*
* BT1120 dec clk is a 5-bit integer division, which is inaccurate in
* most resolutions. So if the frequency division is not accurate, apply
* for a fault tolerance of up 2% in frequency setting, so that the
* obtained frequency is slightly higher than the actual required clk,
* so that the deviation between the actual clk and the required clk
* frequency is not significant.
*/
if (rk628_input_is_bt1120(rk628)) {
rk628_cru_clk_set_rate(rk628, CGU_BT1120DEC, src->clock * 1000);
dec_clk_rate = rk628_cru_clk_get_rate(rk628, CGU_BT1120DEC);
if (dec_clk_rate < src->clock * 1000)
rk628_cru_clk_set_rate(rk628, CGU_BT1120DEC, src->clock * 1020);
}
src_rate = src->clock * 1000;
dst_rate = src_rate * dst->vtotal * dst->htotal;
do_div(dst_rate, (src->vtotal * src->htotal));
do_div(dst_rate, 1000);
dev_info(rk628->dev, "src %dx%d clock:%d\n",
src->hdisplay, src->vdisplay, src->clock);
dev_info(rk628->dev, "dst %dx%d clock:%llu\n",
dst->hdisplay, dst->vdisplay, dst_rate);
rk628_cru_clk_set_rate(rk628, CGU_CLK_RX_READ, src->clock * 1000);
rk628_cru_clk_set_rate(rk628, CGU_SCLK_VOP, dst_rate * 1000);
}

View File

@@ -80,6 +80,7 @@
#define CLK_BT1120DEC_SEL_GPLL 1
#define CLK_BT1120DEC_SEL_CPLL 0
#define CLK_BT1120DEC_DIV(x) HIWORD_UPDATE(x, 4, 0)
#define CLK_BT1120DEC_DIV_MAX GENMASK(4, 0)
#define CRU_CLKSEL_CON03 CRU_REG(0x008c)
#define CRU_CLKSEL_CON04 CRU_REG(0x0090)
#define CLK_HDMIRX_AUD_DIV_MASK GENMASK(13, 6)
@@ -172,10 +173,13 @@
#define CGU_BT1120DEC 37
#define CGU_SCLK_UART 38
#define CGU_CLK_APLL 39
#define CGU_CLK_UART_SRC 40
unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id);
int rk628_cru_clk_set_rate(struct rk628 *rk628, unsigned int id,
unsigned long rate);
void rk628_cru_init(struct rk628 *rk628);
void rk628_cru_create_debugfs_file(struct rk628 *rk628);
void rk628_cru_clk_adjust(struct rk628 *rk628);
#endif

View File

@@ -1227,14 +1227,7 @@ int rk628_hdmirx_enable(struct rk628 *rk628)
return HDMIRX_PLUGIN | HDMIRX_NOSIGNAL;
dev_info(rk628->dev, "hdmirx success\n");
if (rk628->version != RK628D_VERSION) {
/* Try to keep pll frequency close to 1188m */
val = DIV_ROUND_CLOSEST_ULL(1188000000, (src_mode->clock * 1000));
val *= src_mode->clock * 1000;
/* set pll rate according hdmirx tmds clk */
rk628_cru_clk_set_rate(rk628, CGU_CLK_CPLL, val);
msleep(50);
}
rk628_hdmirx_video_unmute(rk628, 1);
return HDMIRX_PLUGIN;

View File

@@ -630,6 +630,33 @@ static enum drm_mode_status
rk628_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct rk628_hdmi *hdmi = connector_to_hdmi(connector);
struct rk628 *rk628 = hdmi->rk628;
/* rk628 hdmitx supports up to 148.5MHz frequency */
if (mode->clock > 148500)
return MODE_CLOCK_HIGH;
/*
* rk628d hdmitx below (including) 40MHz clock frequency (800x600@60Hz),
* hsync and vsync can only output negative polarity
*/
if (rk628->version == RK628D_VERSION && mode->clock <= 40000 &&
(mode->flags & DRM_MODE_FLAG_PHSYNC ||
mode->flags & DRM_MODE_FLAG_PVSYNC))
return MODE_BAD;
if (rk628_input_is_bt1120(rk628) || rk628_input_is_rgb(rk628)) {
/* rk628 bt1120rx cannot be displayed at frequencies below 40MHz. */
if (rk628_input_is_bt1120(rk628) && mode->clock < 40000)
return MODE_CLOCK_LOW;
return MODE_OK;
}
/*
* Unverified pathway retains only 1080p and 720p resolutions
*/
if ((mode->hdisplay == 1920 && mode->vdisplay == 1080) ||
(mode->hdisplay == 1280 && mode->vdisplay == 720))
return MODE_OK;
@@ -677,8 +704,19 @@ static void rk628_hdmi_bridge_mode_set(struct drm_bridge *bridge,
struct rk628_display_mode *src = rk628_display_get_src_mode(rk628);
struct rk628_display_mode *dst = rk628_display_get_dst_mode(rk628);
/* Store the display mode for plugin/DPMS poweron events */
/*
* Store the display mode for plugin/DPMS poweron events. rk628d hdmitx
* below (including) 40MHz clock frequency (800x600@60Hz), hsync and
* vsync can only output negative polarity
*/
memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
if (rk628->version == RK628D_VERSION && mode->clock <= 40000) {
hdmi->previous_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
hdmi->previous_mode.flags |= (DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
}
dst->clock = mode->clock;
dst->hdisplay = mode->hdisplay;
dst->hsync_start = mode->hsync_start;

View File

@@ -1502,20 +1502,6 @@ void rk628_post_process_init(struct rk628 *rk628)
{
struct rk628_display_mode *src = &rk628->src_mode;
const struct rk628_display_mode *dst = &rk628->dst_mode;
u64 dst_rate, src_rate;
src_rate = src->clock * 1000;
dst_rate = src_rate * dst->vtotal * dst->htotal;
do_div(dst_rate, (src->vtotal * src->htotal));
do_div(dst_rate, 1000);
dev_info(rk628->dev, "src %dx%d clock:%d\n",
src->hdisplay, src->vdisplay, src->clock);
dev_info(rk628->dev, "dst %dx%d clock:%llu\n",
dst->hdisplay, dst->vdisplay, dst_rate);
rk628_cru_clk_set_rate(rk628, CGU_CLK_RX_READ, src->clock * 1000);
rk628_cru_clk_set_rate(rk628, CGU_SCLK_VOP, dst_rate * 1000);
if (rk628_output_is_hdmi(rk628)) {
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_VSYNC_POL_MASK,
@@ -1602,6 +1588,7 @@ static void rk628_post_process_csc(struct rk628 *rk628)
void rk628_post_process_enable(struct rk628 *rk628)
{
rk628_cru_clk_adjust(rk628);
/*
* bt1120 needs to configure the timing register, but hdmitx will modify
* the timing as needed, so the bt1120 enable process is moved here.

View File

@@ -269,7 +269,6 @@ static void rk628_bt1120_decoder_timing_cfg(struct rk628 *rk628)
static void rk628_bt1120_decoder_enable(struct rk628 *rk628)
{
struct rk628_display_mode *mode = rk628_display_get_src_mode(rk628);
unsigned long dec_clk_rate;
rk628_set_input_bus_format(rk628, BUS_FMT_YUV422);
@@ -289,19 +288,6 @@ static void rk628_bt1120_decoder_enable(struct rk628 *rk628)
rk628_i2c_write(rk628, CRU_SOFTRST_CON00, 0x10001000);
rk628_i2c_write(rk628, CRU_SOFTRST_CON00, 0x10000000);
/*
* BT1120 dec clk is a 4-bit integer division, which is inaccurate in
* most resolutions. So if the frequency division is not accurate, apply
* for a fault tolerance of up 2% in frequency setting, so that the
* obtained frequency is slightly higher than the actual required clk,
* so that the deviation between the actual clk and the required clk
* frequency is not significant.
*/
rk628_cru_clk_set_rate(rk628, CGU_BT1120DEC, mode->clock * 1000);
dec_clk_rate = rk628_cru_clk_get_rate(rk628, CGU_BT1120DEC);
if (dec_clk_rate < mode->clock * 1000)
rk628_cru_clk_set_rate(rk628, CGU_BT1120DEC, mode->clock * 1020);
if (rk628->rgb.bt1120_dual_edge) {
rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON0,
DEC_DUALEDGE_EN, DEC_DUALEDGE_EN);

View File

@@ -217,6 +217,9 @@ struct rockchip_usb2phy_port_cfg {
* @ls_filter_con: set linestate filter time.
* @port_cfgs: usb-phy port configurations.
* @ls_filter_con: set linestate filter time.
* @refclk_fsel: reference clock frequency select,
* true - select 24 MHz
* false - select 26 MHz
* @chg_det: charger detection registers.
*/
struct rockchip_usb2phy_cfg {
@@ -229,6 +232,7 @@ struct rockchip_usb2phy_cfg {
struct usb2phy_reg clkout_ctl;
struct usb2phy_reg clkout_ctl_phy;
struct usb2phy_reg ls_filter_con;
struct usb2phy_reg refclk_fsel;
const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
const struct rockchip_chg_det_reg chg_det;
};
@@ -580,6 +584,31 @@ err_ret:
return ret;
}
static int rockchip_usb2phy_refclk_set(struct rockchip_usb2phy *rphy)
{
struct regmap *base = get_reg_base(rphy);
struct clk *refclk = of_clk_get_by_name(rphy->dev->of_node, "phyclk");
unsigned long rate;
/* get phy reference clock */
rate = clk_get_rate(refclk);
dev_info(rphy->dev, "refclk freq %ld\n", rate);
switch (rate) {
case 24000000:
property_enable(base, &rphy->phy_cfg->refclk_fsel, true);
break;
case 26000000:
property_enable(base, &rphy->phy_cfg->refclk_fsel, false);
break;
default:
dev_err(rphy->dev, "unsupported refclk freq %ld\n", rate);
return -EINVAL;
}
return 0;
}
static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
{
int ret;
@@ -2382,6 +2411,13 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
else
rphy->num_clks = ret;
/* Set phy Reference clock frequency */
if (rphy->phy_cfg->refclk_fsel.enable) {
ret = rockchip_usb2phy_refclk_set(rphy);
if (ret)
return ret;
}
ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
if (ret)
return ret;
@@ -4009,6 +4045,7 @@ static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
.phy_tuning = rk3576_usb2phy_tuning,
.clkout_ctl = { 0x0008, 0, 0, 1, 0 },
.ls_filter_con = { 0x0020, 19, 0, 0x30100, 0x00020 },
.refclk_fsel = { 0x0004, 2, 0, 0x6, 0x2 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x0000, 8, 0, 0, 0x1d1 },
@@ -4063,6 +4100,7 @@ static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
.phy_tuning = rk3576_usb2phy_tuning,
.clkout_ctl = { 0x2008, 0, 0, 1, 0 },
.ls_filter_con = { 0x2020, 19, 0, 0x30100, 0x00020 },
.refclk_fsel = { 0x2004, 2, 0, 0x6, 0x2 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x2000, 8, 0, 0, 0x1d1 },

View File

@@ -336,7 +336,8 @@ static const struct reg_sequence udphy_24m_refclk_cfg[] = {
{0x0a64, 0xa8}, {0x1a3c, 0xd0},
{0x1a44, 0xd0}, {0x1a48, 0x01},
{0x1a4c, 0x0d}, {0x1a54, 0xe0},
{0x1a5c, 0xe0}, {0x1a64, 0xa8}
{0x1a5c, 0xe0}, {0x1a64, 0xa8},
{0x00D4, 0x30}
};
static const struct reg_sequence udphy_26m_refclk_cfg[] = {
@@ -363,7 +364,7 @@ static const struct reg_sequence udphy_26m_refclk_cfg[] = {
{0x0c30, 0x0E}, {0x0C48, 0x06},
{0x1C30, 0x0E}, {0x1C48, 0x06},
{0x028C, 0x18}, {0x0AF0, 0x00},
{0x1AF0, 0x00}
{0x1AF0, 0x00}, {0x00D4, 0x33}
};
static const struct reg_sequence udphy_init_sequence[] = {
@@ -398,8 +399,7 @@ static const struct reg_sequence udphy_init_sequence[] = {
{0x0070, 0x7D}, {0x0074, 0x68},
{0x0AF4, 0x1A}, {0x1AF4, 0x1A},
{0x0440, 0x3F}, {0x10D4, 0x08},
{0x20D4, 0x08}, {0x00D4, 0x30},
{0x0024, 0x6e},
{0x20D4, 0x08}, {0x0024, 0x6e}
};
static inline int grfreg_write(struct regmap *base,

View File

@@ -307,6 +307,7 @@ static void husb311_remove(struct i2c_client *client)
struct husb311_chip *chip = i2c_get_clientdata(client);
device_init_wakeup(chip->dev, false);
disable_irq(client->irq);
cancel_delayed_work_sync(&chip->pm_work);
tcpci_unregister_port(chip->tcpci);
}
@@ -317,6 +318,7 @@ static void husb311_shutdown(struct i2c_client *client)
husb311_set_vbus(chip->tcpci, &chip->data, false, false);
disable_irq(client->irq);
cancel_delayed_work_sync(&chip->pm_work);
tcpci_unregister_port(chip->tcpci);
}

View File

@@ -189,6 +189,7 @@ union rkvenc2_dual_core_handshake_id {
#define RKVENC2_BIT_VAL_H264 0
#define RKVENC2_BIT_VAL_H265 1
#define RKVENC2_BIT_SLEN_FIFO BIT(30)
#define RKVENC2_BIT_REC_FBC_DIS BIT(31)
#define RKVENC2_REG_SLI_SPLIT (56)
#define RKVENC510_REG_SLI_SPLIT (60)
@@ -270,6 +271,7 @@ struct rkvenc_task {
/* jpege bitstream */
struct mpp_dma_buffer *bs_buf;
u32 offset_bs;
u32 rec_fbc_dis;
};
#define RKVENC_MAX_RCB_NUM (4)
@@ -1112,6 +1114,16 @@ static void *rkvenc_alloc_task(struct mpp_session *session,
task->clk_mode = CLK_MODE_NORMAL;
rkvenc2_check_split_task(mpp, task);
/* check whether the current task is rec_fbc_dis = 1 */
if (task->hw_info->vepu_type == RKVENC_VEPU_510) {
if (task->reg[RKVENC_CLASS_PIC].valid) {
u32 *reg = task->reg[RKVENC_CLASS_PIC].data;
task->rec_fbc_dis = reg[RKVENC510_REG_ENC_PIC] & RKVENC2_BIT_REC_FBC_DIS;
reg[RKVENC510_REG_ENC_PIC] &= ~(RKVENC2_BIT_REC_FBC_DIS);
}
}
mpp_debug_leave();
return mpp_task;
@@ -1423,6 +1435,9 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
if (hw->vepu_type == RKVENC_VEPU_510) {
u32 rec_fbc_dis = task->rec_fbc_dis;
u32 enc_pic = mpp_read(mpp, 0x300);
/*
* Config dvbm special reg to expected that
* vepu will hold when the encoding finish.
@@ -1431,7 +1446,20 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
mpp_write(mpp, 0x308, BIT(18) | BIT(16));
/* Enable slice done interrupt and slice fifo info. */
mpp_write(mpp, 0x20, mpp_read(mpp, 0x20) | BIT(3));
mpp_write(mpp, 0x300, mpp_read(mpp, 0x300) | BIT(30));
/*
* Fix bug:
* Writing reg 0x300 BIT(31) may cause the DMA module to falsely
* trigger writing data. It will case enc err.
* So we need to disable the core clock before writing reg 0x300,
* and re-enable the core clock after writing reg 0x300.
*/
if (rec_fbc_dis) {
mpp_clk_safe_disable(enc->core_clk_info.clk);
mpp_write(mpp, 0x300, enc_pic | BIT(30) | BIT(31));
mpp_clk_safe_enable(enc->core_clk_info.clk);
} else {
mpp_write(mpp, 0x300, enc_pic | BIT(30));
}
}
/* Flush the register before the start the device */

View File

@@ -65,6 +65,9 @@
#define RKVPSS_CMD_MODULE_GET \
_IOR('V', BASE_VIDIOC_PRIVATE + 54, struct rkvpss_module_sel)
#define RKVPSS_CMD_CHECKPARAMS \
_IOW('V', BASE_VIDIOC_PRIVATE + 55, struct rkvpss_frame_cfg)
/********************************************************************/
/* struct rkvpss_mirror_flip

View File

@@ -144,6 +144,10 @@ static const char * const es8323_diff_sel[] = {
"Line 1", "Line 2"
};
static const char * const es8323_adc_data_sel[] = {
"Left Right", "Left Left", "Right Right", "Right Left"
};
SOC_VALUE_ENUM_SINGLE_DECL(es8323_left_dac_enum, ES8323_ADCCONTROL2, 6, 3, es8323_pga_sell, es8323_line_values);
SOC_VALUE_ENUM_SINGLE_DECL(es8323_right_dac_enum, ES8323_ADCCONTROL2, 4, 3, es8323_pga_selr, es8323_line_values);
static SOC_ENUM_SINGLE_DECL(es8323_diff_enum, ES8323_ADCCONTROL3, 7, es8323_diff_sel);
@@ -163,6 +167,7 @@ static const struct soc_enum es8323_enum[] = {
SOC_ENUM_SINGLE(ES8323_ADCCONTROL6, 6, 4, adcpol_txt),
SOC_ENUM_SINGLE(ES8323_ADCCONTROL3, 3, 3, es8323_mono_mux),
SOC_ENUM_SINGLE(ES8323_ADCCONTROL3, 7, 2, es8323_diff_sel),
SOC_ENUM_SINGLE(ES8323_ADCCONTROL4, 6, 4, es8323_adc_data_sel),
};
static const DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 50, 1);
@@ -208,6 +213,7 @@ static const struct snd_kcontrol_new es8323_snd_controls[] = {
ES8323_DACCONTROL25, 0, 33, 0, out_tlv),
SOC_DOUBLE_R_TLV("Output 2 Playback Volume", ES8323_DACCONTROL26,
ES8323_DACCONTROL27, 0, 33, 0, out_tlv),
SOC_ENUM("ADC Data Select", es8323_enum[11]),
};
static const struct snd_kcontrol_new es8323_left_line_controls =