mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
Merge commit '1337cd6a19dc8f7fe0d355334d43b0ef1ba87d0f'
* commit '1337cd6a19dc8f7fe0d355334d43b0ef1ba87d0f': arm64: dts: rockchip: rv1126b-evb1-v10: rockchip_suspend: sleep-debug-en = 1 arm64: dts: rockchip: rv1126b: rockchip_suspend: sleep-debug-en = 0 arm64: dts: rockchip: Add rv1126b-thunder-boot for SPI Nor/eMMC media: rockchip: sc850sl: Support for 40 frame rates arm64: dts: rockchip: rv1126b-evb2-v10: sc485sl enable hw_standby media: rockchip: isp: fix sequence error correction drm/rockchip: vop2: Fix the abnormal brightness when post-csc is enabled media: rockchip: vpss: reset sw_vi2enc_sel on dvbm deinit arm64: dts: rockchip: rk3588-evb: Use the hdmi phy pll dynamic allocation mode media: rockchip: vpss: fix ch5 output issue media: rockchip: vpss: reduce rockit buf vmap video: rockchip: mpp: rkvdec2: Fix reg reading misc: rockchip: pcie-rkep: Fix mutex lock not released in pcie_rkep_release phy: rockchip-snps-pcie3: RK3588 phy lock determines compatibility with all bifurcation situations video: rockchip: rga3: adapt to kernel-6.12 net: r8168: update r8168 driver to v8.055.00 Change-Id: I0670788cb1339561587f40a9825461b1bbae20ae
This commit is contained in:
@@ -280,6 +280,11 @@
|
||||
mem-supply = <&vdd_cpu_big1_mem_s0>;
|
||||
};
|
||||
|
||||
&display_subsystem {
|
||||
clocks = <&hdptxphy_hdmi0>, <&hdptxphy_hdmi1>;
|
||||
clock-names = "hdmi0_phy_pll", "hdmi1_phy_pll";
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
status = "disabled";
|
||||
//rockchip,lane-rate = <1000>;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
&rockchip_suspend {
|
||||
status = "okay";
|
||||
|
||||
rockchip,sleep-debug-en = <1>;
|
||||
|
||||
rockchip,sleep-mode-config = <
|
||||
(0
|
||||
| RKPM_SLP_ARMOFF_LOGOFF
|
||||
|
||||
@@ -588,6 +588,7 @@
|
||||
|
||||
&sc850sl {
|
||||
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
|
||||
rockchip,camera-module-stb = <1>;
|
||||
};
|
||||
|
||||
&sdmmc0 {
|
||||
|
||||
33
arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-emmc.dtsi
Normal file
33
arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-emmc.dtsi
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "rv1126b-thunder-boot.dtsi"
|
||||
|
||||
/ {
|
||||
thunder_boot_mmc: thunder-boot-mmc {
|
||||
compatible = "rockchip,thunder-boot-mmc";
|
||||
reg = <0x21470000 0x4000>;
|
||||
clocks = <&cru HCLK_EMMC>, <&cru CCLK_EMMC>;
|
||||
clock-names = "biu", "ciu";
|
||||
memory-region-src = <&ramdisk_c>;
|
||||
memory-region-dst = <&ramdisk_r>;
|
||||
memory-region-idmac = <&mmc_idmac>;
|
||||
};
|
||||
};
|
||||
|
||||
&emmc {
|
||||
memory-region-ecsd = <&mmc_ecsd>;
|
||||
post-power-on-delay-ms = <0>;
|
||||
};
|
||||
|
||||
&reserved_memory {
|
||||
mmc_ecsd: mmc@47fffe00 {
|
||||
reg = <0x47fffe00 0x00001000>;
|
||||
};
|
||||
|
||||
mmc_idmac: mmc@48000000 {
|
||||
reg = <0x48000000 0x00400000>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "rv1126b-thunder-boot.dtsi"
|
||||
|
||||
/ {
|
||||
thunder_boot_spi_nor: thunder-boot-spi-nor {
|
||||
compatible = "rockchip,thunder-boot-sfc";
|
||||
reg = <0x21460000 0x4000>;
|
||||
memory-region-src = <&ramdisk_c>;
|
||||
memory-region-dst = <&ramdisk_r>;
|
||||
};
|
||||
};
|
||||
95
arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot.dtsi
Normal file
95
arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot.dtsi
Normal file
@@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/ {
|
||||
ramdisk: ramdisk {
|
||||
compatible = "rockchip,ramdisk";
|
||||
memory-region = <&ramdisk_r>;
|
||||
};
|
||||
};
|
||||
|
||||
&reserved_memory {
|
||||
/*
|
||||
* reserved memory layout
|
||||
*
|
||||
* H _______________________
|
||||
* | |
|
||||
* | ramdisk_c |
|
||||
* |_______________________|
|
||||
* | |
|
||||
* | ramdisk_r |
|
||||
* 0x48c40000 |_______________________|
|
||||
* | |
|
||||
* | mcu_log |
|
||||
* 0x48c3c000 |_______________________|
|
||||
* | |
|
||||
* | mcu |
|
||||
* 0x48c00000 |_______________________|
|
||||
* | |
|
||||
* | [TEEOS+TA+SHM] |
|
||||
* 0x48400000 |_______________________|
|
||||
* | |
|
||||
* | isp[0..1]_tb_rmem |
|
||||
* |_______________________|
|
||||
* | |
|
||||
* | meta |
|
||||
* 0x41240000 |_______________________|
|
||||
* | |
|
||||
* | fdt |
|
||||
* 0x41200000 |_______________________|
|
||||
* | |
|
||||
* | kernel_r |
|
||||
* 0x40208000 |_______________________|
|
||||
* | |
|
||||
* | bl31 |
|
||||
* L |_______________________|
|
||||
*
|
||||
*/
|
||||
|
||||
meta: meta@41240000 {
|
||||
/* reg's offset MUST match with RTOS */
|
||||
reg = <0x41240000 0x000c0000>;
|
||||
};
|
||||
|
||||
rkisp_thunderboot: rkisp@41300000 {
|
||||
/* reg's offset MUST match with RTOS */
|
||||
/*
|
||||
* vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
|
||||
* e.g. 1920x1080: 0xa8c000
|
||||
*/
|
||||
reg = <0x41300000 0xa8c000>;
|
||||
};
|
||||
|
||||
rkisp1_thunderboot: rkisp1_thunderboot {
|
||||
/* vicap capture for a second camera */
|
||||
};
|
||||
|
||||
/* Should enable this node if the security feature is enabled, like TA. */
|
||||
tee: tee@48400000 {
|
||||
reg = <0x48400000 0x00800000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
rtos: rtos@48c00000 {
|
||||
reg = <0x48c00000 0x0003a000>;
|
||||
};
|
||||
|
||||
mcu_log: mcu_log@48c3c000 {
|
||||
reg = <0x48c3c000 0x4000>;
|
||||
};
|
||||
|
||||
ramdisk_r: ramdisk_r {
|
||||
reg = <0x48c40000 (10 * 0x00100000)>;
|
||||
};
|
||||
|
||||
ramdisk_c: ramdisk_c {
|
||||
reg = <0x49640000 (5 * 0x00100000)>;
|
||||
};
|
||||
};
|
||||
|
||||
&hw_decompress {
|
||||
memory-region = <&ramdisk_c>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -879,7 +879,7 @@
|
||||
rockchip_suspend: rockchip-suspend {
|
||||
compatible = "rockchip,pm-config";
|
||||
status = "disabled";
|
||||
|
||||
rockchip,sleep-debug-en = <0>;
|
||||
rockchip,sleep-mode-config = <
|
||||
(0
|
||||
| RKPM_SLP_ARMOFF_PMUOFF
|
||||
|
||||
@@ -12888,7 +12888,7 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
||||
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *pstate, *pstate_max = NULL;
|
||||
struct drm_plane_state *pstate, *max_yuv_pstate = NULL;
|
||||
struct vop2_plane_state *vpstate;
|
||||
struct post_csc_coef csc_coef = {};
|
||||
struct post_csc_convert_mode convert_mode = {};
|
||||
@@ -12896,6 +12896,7 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
||||
bool acm_enable;
|
||||
bool post_r2y_en = false;
|
||||
bool post_csc_en = false;
|
||||
bool rgb_limited_plane = false;
|
||||
int range_type;
|
||||
u64 max_yuv_plane = 0, plane_area;
|
||||
enum drm_color_encoding max_yuv_plane_color_encoding = DRM_COLOR_YCBCR_BT601;
|
||||
@@ -12907,13 +12908,17 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
||||
vpstate = to_vop2_plane_state(pstate);
|
||||
dest = &vpstate->dest;
|
||||
|
||||
if (!pstate->fb->format->is_yuv &&
|
||||
pstate->color_range != DRM_COLOR_YCBCR_FULL_RANGE)
|
||||
rgb_limited_plane = true;
|
||||
|
||||
if (pstate->fb->format->is_yuv) {
|
||||
plane_area = drm_rect_width(dest) * drm_rect_height(dest);
|
||||
/* find yuv plane with largest area */
|
||||
if (max_yuv_plane < plane_area) {
|
||||
max_yuv_plane = plane_area;
|
||||
max_yuv_plane_color_encoding = pstate->color_encoding;
|
||||
pstate_max = pstate;
|
||||
max_yuv_pstate = pstate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12948,36 +12953,49 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st
|
||||
if (is_yuv_output(vcstate->bus_format))
|
||||
convert_mode.is_output_yuv = true;
|
||||
|
||||
if (!vcstate->yuv_overlay || vp->has_dci_enabled_win)
|
||||
if (vp->has_dci_enabled_win) {
|
||||
convert_mode.is_input_full_range = true;
|
||||
else if (vcstate->yuv_overlay)
|
||||
} else if (!vcstate->yuv_overlay) {
|
||||
/* if there are yuv planes, choose max plane's range */
|
||||
if (max_yuv_pstate) {
|
||||
/* Todo RGB limit range plane */
|
||||
convert_mode.is_input_full_range = true;
|
||||
} else {
|
||||
if (rgb_limited_plane)
|
||||
convert_mode.is_input_full_range = false;
|
||||
else
|
||||
convert_mode.is_input_full_range = true;
|
||||
}
|
||||
} else {
|
||||
/* yuv overlay range is limited */
|
||||
convert_mode.is_input_full_range = false;
|
||||
else if (pstate_max)
|
||||
convert_mode.is_input_full_range =
|
||||
pstate_max->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
||||
else
|
||||
convert_mode.is_input_full_range =
|
||||
vcstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
||||
}
|
||||
|
||||
convert_mode.is_output_full_range =
|
||||
vcstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0;
|
||||
|
||||
vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_13BIT_DEPTH);
|
||||
|
||||
if (post_csc_en) {
|
||||
convert_mode.output_color_encoding = vcstate->color_encoding;
|
||||
/*
|
||||
* When all layers are rgb, the post-csc input color encoding
|
||||
* is fixed to rgb full, and the value of input_color_encoding
|
||||
* has no actual utility.
|
||||
* If there are any yuv planes, value of post-csc input_color_encoding
|
||||
* selects the value of the yuv plane with the largest area.
|
||||
*/
|
||||
if (!pstate_max && !vcstate->yuv_overlay)
|
||||
convert_mode.intput_color_encoding = vcstate->color_encoding;
|
||||
else
|
||||
convert_mode.intput_color_encoding = max_yuv_plane_color_encoding;
|
||||
convert_mode.output_color_encoding = vcstate->color_encoding;
|
||||
/*
|
||||
* When all layers are rgb, the value of input_color_encoding
|
||||
* has no actual utility, however, the plane csc only supports
|
||||
* limited range under bt709. Therefore, in this scene, the colorspace
|
||||
* of plane csc is selected as bt601. The intput_color_encoding
|
||||
* is consistent with colorspace of plane csc, which is DRM_COLOR_YCBCR_BT601.
|
||||
* If there are any yuv planes, value of post-csc input_color_encoding
|
||||
* selects the value of the yuv plane with the largest area.
|
||||
*/
|
||||
if (!max_yuv_pstate)
|
||||
convert_mode.intput_color_encoding = DRM_COLOR_YCBCR_BT601;
|
||||
else
|
||||
convert_mode.intput_color_encoding = max_yuv_plane_color_encoding;
|
||||
|
||||
if (convert_mode.intput_color_encoding != convert_mode.output_color_encoding ||
|
||||
convert_mode.is_input_full_range != convert_mode.is_output_full_range)
|
||||
post_csc_en = true;
|
||||
|
||||
if (post_csc_en) {
|
||||
rockchip_calc_post_csc(csc, &csc_coef, &convert_mode);
|
||||
|
||||
VOP_MODULE_SET(vop2, vp, csc_coe00, csc_coef.csc_coef00);
|
||||
|
||||
@@ -41,8 +41,10 @@
|
||||
#endif
|
||||
|
||||
#define MIPI_FREQ_540M 540000000
|
||||
#define MIPI_FREQ_972M 486000000
|
||||
#define SC850AI_MAX_LINK_FREQ MIPI_FREQ_540M
|
||||
|
||||
#define SC850SL_MAX_PIXEL_RATE (MIPI_FREQ_540M / 10 * 2 * SC850SL_4LANES)
|
||||
#define SC850SL_MAX_PIXEL_RATE (SC850AI_MAX_LINK_FREQ / 10 * 2 * SC850SL_4LANES)
|
||||
#define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
|
||||
|
||||
#define SC850SL_XVCLK_FREQ_24M 24000000
|
||||
@@ -144,6 +146,7 @@ struct sc850sl_mode {
|
||||
u32 vts_def;
|
||||
u32 exp_def;
|
||||
u32 mipi_freq_idx;
|
||||
u32 xvclk_freq;
|
||||
u32 bpp;
|
||||
const struct regval *reg_list;
|
||||
u32 hdr_mode;
|
||||
@@ -195,7 +198,7 @@ struct sc850sl {
|
||||
#define to_sc850sl(sd) container_of(sd, struct sc850sl, subdev)
|
||||
|
||||
//cleaned_0x20_SC850SL_MIPI_24Minput_1C4D_1080Mbps_10bit_3840x2160_30fps_one_expo.ini
|
||||
static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] = {
|
||||
static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_30fps_regs[] = {
|
||||
{0x0103, 0x01},
|
||||
{0x0100, 0x00},
|
||||
{0x36e9, 0x80},
|
||||
@@ -394,6 +397,208 @@ static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] =
|
||||
{REG_NULL, 0x00},
|
||||
};
|
||||
|
||||
static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_40fps_regs[] = {
|
||||
{0x0103, 0x01},
|
||||
{0x0100, 0x00},
|
||||
{0x36e9, 0x80},
|
||||
{0x36f9, 0x80},
|
||||
{0x36ea, 0x09},
|
||||
{0x36eb, 0x0c},
|
||||
{0x36ec, 0x4b},
|
||||
{0x36ed, 0x34},
|
||||
{0x36fa, 0xcb},
|
||||
{0x36fb, 0x13},
|
||||
{0x36fc, 0x00},
|
||||
{0x36fd, 0x07},
|
||||
{0x36e9, 0x53},
|
||||
{0x36f9, 0x53},
|
||||
{0x3000, 0x01},
|
||||
{0x3018, 0x7a},
|
||||
{0x3019, 0xf0},
|
||||
{0x301a, 0x30},
|
||||
{0x301e, 0x3c},
|
||||
{0x301f, 0x0d},
|
||||
{0x302a, 0x00},
|
||||
{0x3031, 0x0a},
|
||||
{0x3032, 0x20},
|
||||
{0x3033, 0x22},
|
||||
{0x3037, 0x60},
|
||||
{0x303e, 0xb4},
|
||||
{0x3201, 0x98},
|
||||
{0x3203, 0x0c},
|
||||
{0x3205, 0xa7},
|
||||
{0x3207, 0x83},
|
||||
{0x320c, 0x03},
|
||||
{0x320d, 0x39},
|
||||
{0x3211, 0x08},
|
||||
{0x3213, 0x2c},
|
||||
{0x3223, 0xc0},
|
||||
{0x3226, 0x00},
|
||||
{0x3227, 0x03},
|
||||
{0x3230, 0x11},
|
||||
{0x3231, 0x93},
|
||||
{0x3250, 0x40},
|
||||
{0x3253, 0x08},
|
||||
{0x327e, 0x00},
|
||||
{0x3280, 0x00},
|
||||
{0x3281, 0x00},
|
||||
{0x3301, 0x24},
|
||||
{0x3304, 0x30},
|
||||
{0x3306, 0x54},
|
||||
{0x3308, 0x10},
|
||||
{0x3309, 0x60},
|
||||
{0x330a, 0x00},
|
||||
{0x330b, 0xa0},
|
||||
{0x330d, 0x10},
|
||||
{0x3314, 0x92},
|
||||
{0x331e, 0x29},
|
||||
{0x331f, 0x59},
|
||||
{0x3333, 0x10},
|
||||
{0x3347, 0x05},
|
||||
{0x3348, 0xd0},
|
||||
{0x3352, 0x01},
|
||||
{0x3356, 0x38},
|
||||
{0x335d, 0x60},
|
||||
{0x3362, 0x70},
|
||||
{0x338f, 0x80},
|
||||
{0x33af, 0x48},
|
||||
{0x33fe, 0x00},
|
||||
{0x3400, 0x12},
|
||||
{0x3406, 0x04},
|
||||
{0x3410, 0x12},
|
||||
{0x3416, 0x06},
|
||||
{0x3433, 0x01},
|
||||
{0x3440, 0x12},
|
||||
{0x3446, 0x08},
|
||||
{0x3478, 0x01},
|
||||
{0x3479, 0x01},
|
||||
{0x347a, 0x02},
|
||||
{0x347b, 0x01},
|
||||
{0x347c, 0x04},
|
||||
{0x347d, 0x01},
|
||||
{0x3616, 0x0c},
|
||||
{0x3620, 0x94},
|
||||
{0x3622, 0x74},
|
||||
{0x3629, 0x74},
|
||||
{0x362a, 0xf0},
|
||||
{0x362b, 0x0f},
|
||||
{0x362d, 0x00},
|
||||
{0x3630, 0x68},
|
||||
{0x3633, 0x24},
|
||||
{0x3634, 0x22},
|
||||
{0x3635, 0x20},
|
||||
{0x3637, 0x18},
|
||||
{0x3638, 0x26},
|
||||
{0x363b, 0x06},
|
||||
{0x363c, 0x07},
|
||||
{0x363d, 0x05},
|
||||
{0x363e, 0x8f},
|
||||
{0x3648, 0xe0},
|
||||
{0x3649, 0x0a},
|
||||
{0x364a, 0x06},
|
||||
{0x364c, 0x6a},
|
||||
{0x3650, 0x3d},
|
||||
{0x3654, 0x70},
|
||||
{0x3656, 0x68},
|
||||
{0x3657, 0x0f},
|
||||
{0x3658, 0x3d},
|
||||
{0x365c, 0x40},
|
||||
{0x365e, 0x68},
|
||||
{0x3901, 0x04},
|
||||
{0x3902, 0xf1},
|
||||
{0x3904, 0x20},
|
||||
{0x3905, 0x91},
|
||||
{0x391e, 0x03},
|
||||
{0x3928, 0x04},
|
||||
{0x3933, 0xa0},
|
||||
{0x3934, 0x0a},
|
||||
{0x3935, 0x68},
|
||||
{0x3936, 0x00},
|
||||
{0x3937, 0x20},
|
||||
{0x3938, 0x0a},
|
||||
{0x3946, 0x20},
|
||||
{0x3961, 0x40},
|
||||
{0x3962, 0x40},
|
||||
{0x3963, 0xc8},
|
||||
{0x3964, 0xc8},
|
||||
{0x3965, 0x40},
|
||||
{0x3966, 0x40},
|
||||
{0x3967, 0x00},
|
||||
{0x39cd, 0xc8},
|
||||
{0x39ce, 0xc8},
|
||||
{0x3e01, 0x82},
|
||||
{0x3e02, 0x00},
|
||||
{0x3e0e, 0x02},
|
||||
{0x3e0f, 0x00},
|
||||
{0x3e1c, 0x0f},
|
||||
{0x3e23, 0x00},
|
||||
{0x3e24, 0x00},
|
||||
{0x3e53, 0x00},
|
||||
{0x3e54, 0x00},
|
||||
{0x3e68, 0x00},
|
||||
{0x3e69, 0x80},
|
||||
{0x3e73, 0x00},
|
||||
{0x3e74, 0x00},
|
||||
{0x3e86, 0x03},
|
||||
{0x3e87, 0x40},
|
||||
{0x3f02, 0x24},
|
||||
{0x4424, 0x02},
|
||||
{0x4501, 0xb4},
|
||||
{0x4503, 0x20},
|
||||
{0x4509, 0x20},
|
||||
{0x4561, 0x12},
|
||||
{0x4800, 0x24},
|
||||
{0x4837, 0x20},
|
||||
{0x4900, 0x24},
|
||||
{0x4937, 0x16},
|
||||
{0x5000, 0x0e},
|
||||
{0x500f, 0x35},
|
||||
{0x5020, 0x00},
|
||||
{0x5787, 0x10},
|
||||
{0x5788, 0x06},
|
||||
{0x5789, 0x00},
|
||||
{0x578a, 0x18},
|
||||
{0x578b, 0x0c},
|
||||
{0x578c, 0x00},
|
||||
{0x5790, 0x10},
|
||||
{0x5791, 0x06},
|
||||
{0x5792, 0x01},
|
||||
{0x5793, 0x18},
|
||||
{0x5794, 0x0c},
|
||||
{0x5795, 0x01},
|
||||
{0x5799, 0x06},
|
||||
{0x57a2, 0x60},
|
||||
{0x59e0, 0xfe},
|
||||
{0x59e1, 0x40},
|
||||
{0x59e2, 0x38},
|
||||
{0x59e3, 0x30},
|
||||
{0x59e4, 0x20},
|
||||
{0x59e5, 0x38},
|
||||
{0x59e6, 0x30},
|
||||
{0x59e7, 0x20},
|
||||
{0x59e8, 0x3f},
|
||||
{0x59e9, 0x38},
|
||||
{0x59ea, 0x30},
|
||||
{0x59eb, 0x3f},
|
||||
{0x59ec, 0x38},
|
||||
{0x59ed, 0x30},
|
||||
{0x59ee, 0xfe},
|
||||
{0x59ef, 0x40},
|
||||
{0x59f4, 0x38},
|
||||
{0x59f5, 0x30},
|
||||
{0x59f6, 0x20},
|
||||
{0x59f7, 0x38},
|
||||
{0x59f8, 0x30},
|
||||
{0x59f9, 0x20},
|
||||
{0x59fa, 0x3f},
|
||||
{0x59fb, 0x38},
|
||||
{0x59fc, 0x30},
|
||||
{0x59fd, 0x3f},
|
||||
{0x59fe, 0x38},
|
||||
{0x59ff, 0x30},
|
||||
{REG_NULL, 0x00},
|
||||
};
|
||||
|
||||
/*
|
||||
* The width and height must be configured to be
|
||||
* the same as the current output resolution of the sensor.
|
||||
@@ -407,6 +612,26 @@ static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] =
|
||||
* }
|
||||
*/
|
||||
static const struct sc850sl_mode supported_modes[] = {
|
||||
#if defined CONFIG_VIDEO_CAM_SLEEP_WAKEUP
|
||||
{
|
||||
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
|
||||
.width = 3840,
|
||||
.height = 2160,
|
||||
.max_fps = {
|
||||
.numerator = 10000,
|
||||
.denominator = 400000,
|
||||
},
|
||||
.exp_def = 0x08c0,
|
||||
.hts_def = 0x10e0,
|
||||
.vts_def = 0x08ca,
|
||||
.reg_list = sc850sl_linear10bit_3840x2160_40fps_regs,
|
||||
.hdr_mode = NO_HDR,
|
||||
.xvclk_freq = 24000000,
|
||||
.mipi_freq_idx = 1,
|
||||
.bpp = 10,
|
||||
.vc[PAD0] = 0,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
|
||||
.width = 3840,
|
||||
@@ -419,8 +644,9 @@ static const struct sc850sl_mode supported_modes[] = {
|
||||
.hts_def = 0x0226 * 5 - 0x180,
|
||||
.vts_def = 0x08ca,
|
||||
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
|
||||
.reg_list = sc850sl_linear10bit_3840x2160_regs,
|
||||
.reg_list = sc850sl_linear10bit_3840x2160_30fps_regs,
|
||||
.hdr_mode = NO_HDR,
|
||||
.xvclk_freq = 24000000,
|
||||
.mipi_freq_idx = 0,
|
||||
.bpp = 10,
|
||||
.vc[PAD0] = 0,
|
||||
@@ -441,6 +667,7 @@ static const char *const sc850sl_test_pattern_menu[] = {
|
||||
|
||||
static const s64 link_freq_items[] = {
|
||||
MIPI_FREQ_540M,
|
||||
MIPI_FREQ_972M,
|
||||
};
|
||||
|
||||
/* Write registers up to 4 at a time */
|
||||
@@ -1025,6 +1252,7 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
|
||||
case RKMODULE_SET_QUICK_STREAM:
|
||||
stream = *((u32 *)arg);
|
||||
dev_info(&sc850sl->client->dev, "stream: %d\n", stream);
|
||||
|
||||
if (stream) {
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x3019,
|
||||
@@ -1354,10 +1582,10 @@ static int __sc850sl_power_on(struct sc850sl *sc850sl)
|
||||
if (ret < 0)
|
||||
dev_err(dev, "could not set pins\n");
|
||||
}
|
||||
ret = clk_set_rate(sc850sl->xvclk, SC850SL_XVCLK_FREQ_24M);
|
||||
ret = clk_set_rate(sc850sl->xvclk, sc850sl->cur_mode->xvclk_freq);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "Failed to set xvclk rate 24MHz\n");
|
||||
if (clk_get_rate(sc850sl->xvclk) != SC850SL_XVCLK_FREQ_24M)
|
||||
if (clk_get_rate(sc850sl->xvclk) != sc850sl->cur_mode->xvclk_freq)
|
||||
dev_warn(dev, "xvclk mismatched\n");
|
||||
ret = clk_prepare_enable(sc850sl->xvclk);
|
||||
if (ret < 0) {
|
||||
@@ -1973,7 +2201,7 @@ static int sc850sl_probe(struct i2c_client *client,
|
||||
#endif
|
||||
if (!sc850sl->cam_sw_info) {
|
||||
sc850sl->cam_sw_info = cam_sw_init();
|
||||
cam_sw_clk_init(sc850sl->cam_sw_info, sc850sl->xvclk, SC850SL_XVCLK_FREQ_24M);
|
||||
cam_sw_clk_init(sc850sl->cam_sw_info, sc850sl->xvclk, sc850sl->cur_mode->xvclk_freq);
|
||||
cam_sw_reset_pin_init(sc850sl->cam_sw_info, sc850sl->reset_gpio, 0);
|
||||
cam_sw_pwdn_pin_init(sc850sl->cam_sw_info, sc850sl->pwdn_gpio, 1);
|
||||
}
|
||||
|
||||
@@ -4242,7 +4242,7 @@ static int rkisp_vicap_sof(struct rkisp_device *dev, struct rkisp_vicap_sof *sof
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"vicap sof %d, isp sof %d\n",
|
||||
sof->sequence, dev->dmarx_dev.cur_frame.id);
|
||||
dev->dmarx_dev.cur_frame.id = sof->sequence;
|
||||
dev->dmarx_dev.cur_frame.id = sof->sequence - 1;
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->rdbk_lock, flag);
|
||||
return 0;
|
||||
|
||||
@@ -51,6 +51,12 @@ enum {
|
||||
ROCKIT_DVBM_START,
|
||||
};
|
||||
|
||||
enum {
|
||||
DVBM_DEINIT = 0,
|
||||
DVBM_ONLINE = 1,
|
||||
DVBM_OFFLINE = 2,
|
||||
};
|
||||
|
||||
enum rkvpss_fmt_pix_type {
|
||||
FMT_YUV,
|
||||
FMT_RGB,
|
||||
@@ -112,6 +118,7 @@ static inline int vpss_outchn_max(int version)
|
||||
}
|
||||
|
||||
extern int rkvpss_debug;
|
||||
extern int rkvpss_buf_dbg;
|
||||
extern struct platform_driver rkvpss_plat_drv;
|
||||
extern int rkvpss_cfginfo_num;
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ int rkvpss_debug;
|
||||
module_param_named(debug, rkvpss_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Debug level (0-6)");
|
||||
|
||||
int rkvpss_buf_dbg;
|
||||
module_param_named(buf_dbg, rkvpss_buf_dbg, int, 0644);
|
||||
MODULE_PARM_DESC(buf_dbg, "rkvpss buf dbg");
|
||||
|
||||
static bool rkvpss_clk_dbg;
|
||||
module_param_named(clk_dbg, rkvpss_clk_dbg, bool, 0644);
|
||||
MODULE_PARM_DESC(clk_dbg, "rkvpss clk set by user");
|
||||
|
||||
@@ -70,6 +70,8 @@ struct rkvpss_hw_dev {
|
||||
bool is_suspend;
|
||||
bool is_first;
|
||||
bool is_probe_end;
|
||||
int dvbm_refcnt;
|
||||
int dvbm_flag;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VIDEO_ROCKCHIP_VPSS_V10
|
||||
|
||||
@@ -746,9 +746,9 @@ static struct stream_config scl5_config = {
|
||||
.uv_offs_cnt = RKVPSS2X_MI_CHN5_WR_CB_OFFS_CNT,
|
||||
.y_pic_width = RKVPSS2X_MI_CHN5_WR_Y_PIC_WIDTH,
|
||||
.y_pic_size = RKVPSS2X_MI_CHN5_WR_Y_PIC_SIZE,
|
||||
.ctrl_shd = RKVPSS2X_MI_CHN4_WR_CTRL_SHD,
|
||||
.y_shd = RKVPSS2X_MI_CHN4_WR_Y_BASE_SHD,
|
||||
.uv_shd = RKVPSS2X_MI_CHN4_WR_CB_BASE_SHD,
|
||||
.ctrl_shd = RKVPSS2X_MI_CHN5_WR_CTRL_SHD,
|
||||
.y_shd = RKVPSS2X_MI_CHN5_WR_Y_BASE_SHD,
|
||||
.uv_shd = RKVPSS2X_MI_CHN5_WR_CB_BASE_SHD,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -887,7 +887,7 @@ static void scl_force_update(struct rkvpss_stream *stream)
|
||||
val = RKVPSS2X_MI_CHN4_FORCE_UPD;
|
||||
break;
|
||||
case RKVPSS_OUTPUT_CH5:
|
||||
val = RKVPSS2X_MI_CHN4_FORCE_UPD;
|
||||
val = RKVPSS2X_MI_CHN5_FORCE_UPD;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -1129,7 +1129,7 @@ static void scl_disable_mi(struct rkvpss_stream *stream)
|
||||
val = RKVPSS2X_ISP2VPSS_CHN4_SEL(3);
|
||||
break;
|
||||
case RKVPSS_OUTPUT_CH5:
|
||||
val = RKVPSS2X_ISP2VPSS_CHN4_SEL(3);
|
||||
val = RKVPSS2X_ISP2VPSS_CHN5_SEL(3);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -1992,6 +1992,13 @@ static void rkvpss_stop_streaming(struct vb2_queue *queue)
|
||||
destroy_buf_queue(stream, VB2_BUF_STATE_ERROR);
|
||||
rkvpss_pipeline_close(dev);
|
||||
tasklet_disable(&stream->buf_done_tasklet);
|
||||
|
||||
if (hw->dvbm_refcnt <= 0 && hw->dvbm_flag != DVBM_OFFLINE) {
|
||||
v4l2_dbg(2, rkvpss_debug, &dev->v4l2_dev, "%s: clear vpss2enc_sel\n", __func__);
|
||||
rkvpss_hw_clear_bits(hw, RKVPSS_VPSS_CTRL, RKVPSS_VPSS2ENC_SEL);
|
||||
hw->dvbm_refcnt = 0;
|
||||
}
|
||||
|
||||
v4l2_dbg(1, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s %s id:%d exit\n", __func__,
|
||||
node->vdev.name, stream->id);
|
||||
@@ -2103,7 +2110,10 @@ static int rkvpss_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
goto pipe_close;
|
||||
}
|
||||
if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)
|
||||
rkvpss_dvbm_init(stream);
|
||||
if (rkvpss_dvbm_init(stream) != 0) {
|
||||
v4l2_err(&dev->v4l2_dev, "dvbm init failed\n");
|
||||
goto stop_stream;
|
||||
}
|
||||
ret = rkvpss_pipeline_stream(dev, true);
|
||||
if (ret < 0)
|
||||
goto stop_stream;
|
||||
|
||||
@@ -50,6 +50,14 @@ int rkvpss_dvbm_init(struct rkvpss_stream *stream)
|
||||
|
||||
if (!g_dvbm)
|
||||
return -EINVAL;
|
||||
if (vpss_dev->hw_dev->dvbm_flag == DVBM_OFFLINE) {
|
||||
v4l2_err(&vpss_dev->v4l2_dev,
|
||||
"offline dvbm already set, online dvbm set fail.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vpss_dev->hw_dev->dvbm_refcnt++;
|
||||
vpss_dev->hw_dev->dvbm_flag = DVBM_ONLINE;
|
||||
|
||||
width = stream->out_fmt.plane_fmt[0].bytesperline;
|
||||
height = stream->out_fmt.height;
|
||||
@@ -76,6 +84,11 @@ void rkvpss_dvbm_deinit(struct rkvpss_device *vpss_dev)
|
||||
pr_err("g_dvbm %p or vpss_dev %p is NULL\n", g_dvbm, vpss_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
vpss_dev->hw_dev->dvbm_refcnt--;
|
||||
if (vpss_dev->hw_dev->dvbm_refcnt <= 0)
|
||||
vpss_dev->hw_dev->dvbm_flag = DVBM_DEINIT;
|
||||
|
||||
rk_dvbm_unlink(g_dvbm, vpss_dev->dev_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,13 +38,20 @@ int rkvpss_ofl_dvbm_get(struct rkvpss_offline_dev *ofl)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rkvpss_ofl_dvbm_init(struct dma_buf *dbuf, u32 dma_addr, u32 wrap_line,
|
||||
int width, int height, int id)
|
||||
int rkvpss_ofl_dvbm_init(struct rkvpss_offline_dev *ofl, struct dma_buf *dbuf, u32 dma_addr,
|
||||
u32 wrap_line, int width, int height, int id)
|
||||
{
|
||||
struct dvbm_isp_cfg_t dvbm_cfg;
|
||||
|
||||
if (!g_ofl_dvbm)
|
||||
return -EINVAL;
|
||||
if (ofl->hw->dvbm_flag == DVBM_ONLINE) {
|
||||
v4l2_err(&ofl->v4l2_dev,
|
||||
"online dvbm already set, offline dvbm set fail.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ofl->hw->dvbm_flag = DVBM_OFFLINE;
|
||||
|
||||
dvbm_cfg.dma_addr = dma_addr;
|
||||
dvbm_cfg.buf = dbuf;
|
||||
@@ -70,7 +77,10 @@ void rkvpss_ofl_dvbm_deinit(struct rkvpss_offline_dev *ofl, int id)
|
||||
pr_err("g_dvbm %p or vpss_dev %p is NULL\n", g_ofl_dvbm, ofl);
|
||||
return;
|
||||
}
|
||||
ofl->hw->dvbm_flag = DVBM_DEINIT;
|
||||
rk_dvbm_unlink(g_ofl_dvbm, id);
|
||||
v4l2_dbg(2, rkvpss_debug, &ofl->v4l2_dev, "%s: clear vpss2enc_sel\n", __func__);
|
||||
rkvpss_hw_clear_bits(ofl->hw, RKVPSS_VPSS_CTRL, RKVPSS_VPSS2ENC_SEL);
|
||||
}
|
||||
|
||||
int rkvpss_ofl_dvbm_event(u32 event, u32 seq)
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
|
||||
#if IS_ENABLED(CONFIG_ROCKCHIP_DVBM)
|
||||
int rkvpss_ofl_dvbm_get(struct rkvpss_offline_dev *ofl);
|
||||
int rkvpss_ofl_dvbm_init(struct dma_buf *dbuf, u32 dma_addr, u32 wrap_line, int width, int height, int id);
|
||||
int rkvpss_ofl_dvbm_init(struct rkvpss_offline_dev *ofl, struct dma_buf *dbuf,
|
||||
u32 dma_addr, u32 wrap_line, int width, int height, int id);
|
||||
void rkvpss_ofl_dvbm_deinit(struct rkvpss_offline_dev *ofl, int id);
|
||||
int rkvpss_ofl_dvbm_event(u32 event, u32 seq);
|
||||
#else
|
||||
static inline int rkvpss_ofl_dvbm_get(struct rkvpss_offline_dev *ofl) {return -EINVAL; }
|
||||
static inline int rkvpss_ofl_dvbm_init(struct dma_buf *dbuf, u32 dma_addr, u32 wrap_line, int width, int height, int id) {return -EINVAL; }
|
||||
static inline int rkvpss_ofl_dvbm_init(struct rkvpss_offline_dev *ofl, struct dma_buf *dbuf,
|
||||
u32 dma_addr, u32 wrap_line, int width, int height,
|
||||
int id) {return -EINVAL; }
|
||||
static inline void rkvpss_ofl_dvbm_deinit(struct rkvpss_offline_dev *ofl, int id) {}
|
||||
static inline int rkvpss_ofl_dvbm_event(u32 event, u32 seq) {return -EINVAL; }
|
||||
#endif
|
||||
|
||||
@@ -2438,7 +2438,7 @@ static long rkvpss_ofl_wrap_dvbm_init(struct rkvpss_offline_dev *ofl,
|
||||
|
||||
wrap_line = cfg->output[i].wrap.wrap_line;
|
||||
|
||||
rkvpss_ofl_dvbm_init(dbuf, dma_addr, wrap_line, width, height, cfg->dev_id);
|
||||
rkvpss_ofl_dvbm_init(ofl, dbuf, dma_addr, wrap_line, width, height, cfg->dev_id);
|
||||
|
||||
v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev, "%s file_id:%d dev_id:%d wrap_chn:%d\n",
|
||||
__func__, file_id, cfg->dev_id, i);
|
||||
|
||||
@@ -216,8 +216,13 @@ int rkvpss_rockit_buf_queue(struct rockit_rkvpss_cfg *input_cfg)
|
||||
}
|
||||
|
||||
vpssrk_buf->vaddr = NULL;
|
||||
if (dma_buf_vmap(input_cfg->buf, &map) == 0)
|
||||
vpssrk_buf->vaddr = map.vaddr;
|
||||
/* default vmap two to get image, rkvpss_buf_dbg > 0 to vmap all */
|
||||
if (i < 2 || rkvpss_buf_dbg > 0) {
|
||||
v4l2_dbg(3, rkvpss_debug, &vpss_dev->v4l2_dev,
|
||||
"stream:%d rockit vmap buf:%p\n", stream->id, input_cfg->buf);
|
||||
if (dma_buf_vmap(input_cfg->buf, &map) == 0)
|
||||
vpssrk_buf->vaddr = map.vaddr;
|
||||
}
|
||||
|
||||
vpssrk_buf->buff_addr = sg_dma_address(sgt->sgl);
|
||||
get_dma_buf(input_cfg->buf);
|
||||
|
||||
@@ -351,8 +351,10 @@ static int pcie_rkep_release(struct inode *inode, struct file *file)
|
||||
mutex_lock(&pcie_file->file_lock_mutex);
|
||||
index = find_first_bit(pcie_file->child_vid_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
|
||||
|
||||
if (index >= RKEP_EP_VIRTUAL_ID_MAX)
|
||||
if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
|
||||
mutex_unlock(&pcie_file->file_lock_mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
__clear_bit(index, pcie_file->child_vid_bitmap);
|
||||
mutex_unlock(&pcie_file->file_lock_mutex);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
@@ -44,6 +44,11 @@ ENABLE_S0_MAGIC_PACKET = n
|
||||
CONFIG_DYNAMIC_ASPM = y
|
||||
ENABLE_USE_FIRMWARE_FILE = n
|
||||
CONFIG_CTAP_SHORT_OFF = n
|
||||
ENABLE_MULTIPLE_TX_QUEUE = n
|
||||
ENABLE_RSS_SUPPORT = n
|
||||
ENABLE_LIB_SUPPORT = n
|
||||
DISABLE_WOL_SUPPORT = n
|
||||
ENABLE_GIGA_LITE = y
|
||||
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
obj-$(CONFIG_R8168) := r8168.o
|
||||
@@ -67,7 +72,9 @@ ifneq ($(KERNELRELEASE),)
|
||||
r8168-objs += r8168_dash.o
|
||||
EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT
|
||||
endif
|
||||
EXTRA_CFLAGS += -DCONFIG_R8168_NAPI
|
||||
ifneq ($(ENABLE_RSS_SUPPORT), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_R8168_NAPI
|
||||
endif
|
||||
EXTRA_CFLAGS += -DCONFIG_R8168_VLAN
|
||||
ifeq ($(CONFIG_DOWN_SPEED_100), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100
|
||||
@@ -97,6 +104,23 @@ ifneq ($(KERNELRELEASE),)
|
||||
ifeq ($(CONFIG_CTAP_SHORT_OFF), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_CTAP_SHORT_OFF
|
||||
endif
|
||||
ifeq ($(ENABLE_MULTIPLE_TX_QUEUE), y)
|
||||
EXTRA_CFLAGS += -DENABLE_MULTIPLE_TX_QUEUE
|
||||
endif
|
||||
ifeq ($(ENABLE_RSS_SUPPORT), y)
|
||||
r8168-objs += r8168_rss.o
|
||||
EXTRA_CFLAGS += -DENABLE_RSS_SUPPORT
|
||||
endif
|
||||
ifeq ($(ENABLE_LIB_SUPPORT), y)
|
||||
r8168-objs += r8168_lib.o
|
||||
EXTRA_CFLAGS += -DENABLE_LIB_SUPPORT
|
||||
endif
|
||||
ifeq ($(DISABLE_WOL_SUPPORT), y)
|
||||
EXTRA_CFLAGS += -DDISABLE_WOL_SUPPORT
|
||||
endif
|
||||
ifeq ($(ENABLE_GIGA_LITE), y)
|
||||
EXTRA_CFLAGS += -DENABLE_GIGA_LITE
|
||||
endif
|
||||
else
|
||||
BASEDIR := /lib/modules/$(shell uname -r)
|
||||
KERNELDIR ?= $(BASEDIR)/build
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
@@ -60,7 +60,6 @@ int rtl8168_asf_ioctl(struct net_device *dev,
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
void *user_data = ifr->ifr_data;
|
||||
struct asf_ioctl_struct asf_usrdata;
|
||||
unsigned long flags;
|
||||
|
||||
if (tp->mcfg != CFG_METHOD_7 && tp->mcfg != CFG_METHOD_8)
|
||||
return -EOPNOTSUPP;
|
||||
@@ -68,8 +67,6 @@ int rtl8168_asf_ioctl(struct net_device *dev,
|
||||
if (copy_from_user(&asf_usrdata, user_data, sizeof(struct asf_ioctl_struct)))
|
||||
return -EFAULT;
|
||||
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
|
||||
switch (asf_usrdata.offset) {
|
||||
case HBPeriod:
|
||||
rtl8168_asf_hbperiod(tp, asf_usrdata.arg, asf_usrdata.u.data);
|
||||
@@ -192,12 +189,9 @@ int rtl8168_asf_ioctl(struct net_device *dev,
|
||||
rtl8168_asf_key_access(tp, asf_usrdata.arg, KR, asf_usrdata.u.data);
|
||||
break;
|
||||
default:
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(user_data, &asf_usrdata, sizeof(struct asf_ioctl_struct)))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -390,10 +384,10 @@ void rtl8168_asf_rw_systemid(struct rtl8168_private *tp, int arg, unsigned int *
|
||||
int i;
|
||||
|
||||
if (arg == ASF_GET)
|
||||
for (i = 0; i < SYSID_LEN ; i++)
|
||||
for (i = 0; i < SYSID_LEN; i++)
|
||||
data[i] = rtl8168_eri_read(tp, SysID + i, RW_ONE_BYTE, ERIAR_ASF);
|
||||
else /* arg == ASF_SET */
|
||||
for (i = 0; i < SYSID_LEN ; i++)
|
||||
for (i = 0; i < SYSID_LEN; i++)
|
||||
rtl8168_eri_write(tp, SysID + i, RW_ONE_BYTE, data[i], ERIAR_ASF);
|
||||
}
|
||||
|
||||
@@ -414,9 +408,9 @@ void rtl8168_asf_rw_uuid(struct rtl8168_private *tp, int arg, unsigned int *data
|
||||
int i, j;
|
||||
|
||||
if (arg == ASF_GET)
|
||||
for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++)
|
||||
for (i = UUID_LEN - 1, j = 0; i >= 0; i--, j++)
|
||||
data[j] = rtl8168_eri_read(tp, UUID + i, RW_ONE_BYTE, ERIAR_ASF);
|
||||
else /* arg == ASF_SET */
|
||||
for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++)
|
||||
for (i = UUID_LEN - 1, j = 0; i >= 0; i--, j++)
|
||||
rtl8168_eri_write(tp, UUID + i, RW_ONE_BYTE, data[j], ERIAR_ASF);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
@@ -160,6 +160,7 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2;
|
||||
#define OCP_REG_CR (0x36)
|
||||
#define OCP_REG_DMEMSTA (0x38)
|
||||
#define OCP_REG_GPHYAR (0x60)
|
||||
#define OCP_REG_FIRMWARE_MAJOR_VERSION (0x120)
|
||||
|
||||
|
||||
#define OCP_REG_CONFIG0_DASHEN BIT_15
|
||||
@@ -175,6 +176,9 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2;
|
||||
#define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1)
|
||||
#define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2)
|
||||
#define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3)
|
||||
#define HW_DASH_SUPPORT_CMAC(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || HW_DASH_SUPPORT_TYPE_3(_M))
|
||||
#define HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || \
|
||||
HW_DASH_SUPPORT_TYPE_3(_M))
|
||||
|
||||
#define RECV_FROM_FW_BUF_SIZE (2048)
|
||||
#define SEND_TO_FW_BUF_SIZE (2048)
|
||||
@@ -247,6 +251,7 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2;
|
||||
#define RTL_CMAC_R32(tp, reg) ((unsigned long) readl (tp->cmac_ioaddr + (reg)))
|
||||
|
||||
int rtl8168_dash_ioctl(struct net_device *dev, struct ifreq *ifr);
|
||||
bool CheckDashInterrupt(struct net_device *dev, u16 status);
|
||||
void HandleDashInterrupt(struct net_device *dev);
|
||||
int AllocateDashShareMemory(struct net_device *dev);
|
||||
void FreeAllocatedDashShareMemory(struct net_device *dev);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek 2.5Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
482
drivers/net/ethernet/realtek/r8168/r8168_rss.c
Normal file
482
drivers/net/ethernet/realtek/r8168/r8168_rss.c
Normal file
@@ -0,0 +1,482 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
################################################################################
|
||||
#
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Author:
|
||||
# Realtek NIC software team <nicfae@realtek.com>
|
||||
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
|
||||
#
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
* This product is covered by one or more of the following patents:
|
||||
* US6,570,884, US6,115,776, and US6,327,625.
|
||||
***********************************************************************************/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include "r8168.h"
|
||||
|
||||
enum rtl8168_rss_register_content {
|
||||
/* RSS */
|
||||
RSS_CTRL_TCP_IPV4_SUPP = (1 << 0),
|
||||
RSS_CTRL_IPV4_SUPP = (1 << 1),
|
||||
RSS_CTRL_TCP_IPV6_SUPP = (1 << 2),
|
||||
RSS_CTRL_IPV6_SUPP = (1 << 3),
|
||||
RSS_CTRL_IPV6_EXT_SUPP = (1 << 4),
|
||||
RSS_CTRL_TCP_IPV6_EXT_SUPP = (1 << 5),
|
||||
RSS_HALF_SUPP = (1 << 7),
|
||||
RSS_QUAD_CPU_EN = (1 << 16),
|
||||
RSS_HQ_Q_SUP_R = (1 << 31),
|
||||
};
|
||||
|
||||
static int rtl8168_get_rss_hash_opts(struct rtl8168_private *tp,
|
||||
struct ethtool_rxnfc *cmd)
|
||||
{
|
||||
cmd->data = 0;
|
||||
|
||||
/* Report default options for RSS */
|
||||
switch (cmd->flow_type) {
|
||||
case TCP_V4_FLOW:
|
||||
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
|
||||
fallthrough;
|
||||
case IPV4_FLOW:
|
||||
cmd->data |= RXH_IP_SRC | RXH_IP_DST;
|
||||
break;
|
||||
case TCP_V6_FLOW:
|
||||
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
|
||||
fallthrough;
|
||||
case IPV6_FLOW:
|
||||
cmd->data |= RXH_IP_SRC | RXH_IP_DST;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
||||
u32 *rule_locs)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (!(dev->features & NETIF_F_RXHASH))
|
||||
return ret;
|
||||
|
||||
switch (cmd->cmd) {
|
||||
case ETHTOOL_GRXRINGS:
|
||||
cmd->data = rtl8168_tot_rx_rings(tp);
|
||||
ret = 0;
|
||||
break;
|
||||
case ETHTOOL_GRXFH:
|
||||
ret = rtl8168_get_rss_hash_opts(tp, cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp)
|
||||
{
|
||||
return tp->HwSuppIndirTblEntries;
|
||||
}
|
||||
|
||||
#define RSS_MASK_BITS_OFFSET (8)
|
||||
static int _rtl8168_set_rss_hash_opt(struct rtl8168_private *tp)
|
||||
{
|
||||
u32 hash_mask_len;
|
||||
u32 rss_ctrl;
|
||||
|
||||
/* Perform hash on these packet types */
|
||||
rss_ctrl = RSS_CTRL_TCP_IPV4_SUPP
|
||||
| RSS_CTRL_IPV4_SUPP
|
||||
| RSS_CTRL_IPV6_SUPP
|
||||
| RSS_CTRL_IPV6_EXT_SUPP
|
||||
| RSS_CTRL_TCP_IPV6_SUPP
|
||||
| RSS_CTRL_TCP_IPV6_EXT_SUPP;
|
||||
|
||||
if (R8168_MULTI_RSS_4Q(tp))
|
||||
rss_ctrl |= RSS_QUAD_CPU_EN;
|
||||
|
||||
hash_mask_len = ilog2(rtl8168_rss_indir_tbl_entries(tp));
|
||||
hash_mask_len &= (BIT_0 | BIT_1 | BIT_2);
|
||||
rss_ctrl |= hash_mask_len << RSS_MASK_BITS_OFFSET;
|
||||
|
||||
rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8168_set_rss_hash_opt(struct rtl8168_private *tp,
|
||||
struct ethtool_rxnfc *nfc)
|
||||
{
|
||||
u32 rss_flags = tp->rss_flags;
|
||||
|
||||
/*
|
||||
* RSS does not support anything other than hashing
|
||||
* to queues on src and dst IPs and ports
|
||||
*/
|
||||
if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
|
||||
RXH_L4_B_0_1 | RXH_L4_B_2_3))
|
||||
return -EINVAL;
|
||||
|
||||
switch (nfc->flow_type) {
|
||||
case TCP_V4_FLOW:
|
||||
case TCP_V6_FLOW:
|
||||
if (!(nfc->data & RXH_IP_SRC) ||
|
||||
!(nfc->data & RXH_IP_DST) ||
|
||||
!(nfc->data & RXH_L4_B_0_1) ||
|
||||
!(nfc->data & RXH_L4_B_2_3))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SCTP_V4_FLOW:
|
||||
case AH_ESP_V4_FLOW:
|
||||
case AH_V4_FLOW:
|
||||
case ESP_V4_FLOW:
|
||||
case SCTP_V6_FLOW:
|
||||
case AH_ESP_V6_FLOW:
|
||||
case AH_V6_FLOW:
|
||||
case ESP_V6_FLOW:
|
||||
case IP_USER_FLOW:
|
||||
case ETHER_FLOW:
|
||||
/* RSS is not supported for these protocols */
|
||||
if (nfc->data) {
|
||||
netif_err(tp, drv, tp->dev, "Command parameters not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* if we changed something we need to update flags */
|
||||
if (rss_flags != tp->rss_flags) {
|
||||
u32 rss_ctrl = rtl8168_eri_read(tp, RSS_CTRL_8168, 4, ERIAR_ExGMAC);
|
||||
|
||||
tp->rss_flags = rss_flags;
|
||||
|
||||
/* Perform hash on these packet types */
|
||||
rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP
|
||||
| RSS_CTRL_IPV4_SUPP
|
||||
| RSS_CTRL_IPV6_SUPP
|
||||
| RSS_CTRL_IPV6_EXT_SUPP
|
||||
| RSS_CTRL_TCP_IPV6_SUPP
|
||||
| RSS_CTRL_TCP_IPV6_EXT_SUPP;
|
||||
|
||||
if (R8168_MULTI_RSS_4Q(tp))
|
||||
rss_ctrl |= RSS_QUAD_CPU_EN;
|
||||
else
|
||||
rss_ctrl &= ~RSS_QUAD_CPU_EN;
|
||||
|
||||
rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (!(dev->features & NETIF_F_RXHASH))
|
||||
return ret;
|
||||
|
||||
switch (cmd->cmd) {
|
||||
case ETHTOOL_SRXFH:
|
||||
ret = rtl8168_set_rss_hash_opt(tp, cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 _rtl8168_get_rxfh_key_size(struct rtl8168_private *tp)
|
||||
{
|
||||
return sizeof(tp->rss_key);
|
||||
}
|
||||
|
||||
u32 rtl8168_get_rxfh_key_size(struct net_device *dev)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
|
||||
if (!(dev->features & NETIF_F_RXHASH))
|
||||
return 0;
|
||||
|
||||
return _rtl8168_get_rxfh_key_size(tp);
|
||||
}
|
||||
|
||||
u32 rtl8168_rss_indir_size(struct net_device *dev)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
|
||||
if (!(dev->features & NETIF_F_RXHASH))
|
||||
return 0;
|
||||
|
||||
return rtl8168_rss_indir_tbl_entries(tp);
|
||||
}
|
||||
|
||||
static void rtl8168_get_reta(struct rtl8168_private *tp, u32 *indir)
|
||||
{
|
||||
int i, reta_size = rtl8168_rss_indir_tbl_entries(tp);
|
||||
|
||||
for (i = 0; i < reta_size; i++)
|
||||
indir[i] = tp->rss_indir_tbl[i];
|
||||
}
|
||||
|
||||
static u32 rtl8168_rss_key_reg(struct rtl8168_private *tp)
|
||||
{
|
||||
return RSS_KEY_8168;
|
||||
}
|
||||
|
||||
static u32 rtl8168_rss_indir_tbl_reg(struct rtl8168_private *tp)
|
||||
{
|
||||
return Rss_indir_tbl;
|
||||
}
|
||||
|
||||
static void rtl8168_store_reta(struct rtl8168_private *tp)
|
||||
{
|
||||
u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
|
||||
u16 indir_tbl_reg = rtl8168_rss_indir_tbl_reg(tp);
|
||||
u32 hw_indir[RTL8168_RSS_INDIR_TBL_SIZE] = {0};
|
||||
u8 *indir = tp->rss_indir_tbl;
|
||||
u32 bit_on_cnt = 0x00000001;
|
||||
u32 i, j;
|
||||
|
||||
/* Mapping redirection table to HW */
|
||||
for (i = 0, j = 0; i < reta_entries; i++) {
|
||||
if ((indir[i] & 2) && R8168_MULTI_RSS_4Q(tp))
|
||||
hw_indir[j + 4] |= bit_on_cnt;
|
||||
if (indir[i] & 1)
|
||||
hw_indir[j] |= bit_on_cnt;
|
||||
|
||||
if (bit_on_cnt == 0x80000000) {
|
||||
bit_on_cnt = 0x00000001;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
bit_on_cnt <<= 1;
|
||||
}
|
||||
|
||||
/* Write redirection table to HW */
|
||||
for (i = 0; i < RTL8168_RSS_INDIR_TBL_SIZE; i++)
|
||||
RTL_W32(tp, indir_tbl_reg + i*4, hw_indir[i]);
|
||||
}
|
||||
|
||||
static void rtl8168_store_rss_key(struct rtl8168_private *tp)
|
||||
{
|
||||
const u16 rss_key_reg = rtl8168_rss_key_reg(tp);
|
||||
u32 i, rss_key_size = _rtl8168_get_rxfh_key_size(tp);
|
||||
u32 *rss_key = (u32*)tp->rss_key;
|
||||
|
||||
/* Write redirection table to HW */
|
||||
for (i = 0; i < rss_key_size; i+=4)
|
||||
rtl8168_eri_write(tp, rss_key_reg + i, 4, *rss_key++, ERIAR_ExGMAC);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
|
||||
int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
|
||||
if (!(dev->features & NETIF_F_RXHASH))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
rxfh->hfunc = ETH_RSS_HASH_TOP;
|
||||
|
||||
if (rxfh->indir)
|
||||
rtl8168_get_reta(tp, rxfh->indir);
|
||||
|
||||
if (rxfh->key)
|
||||
memcpy(rxfh->key, tp->rss_key, RTL8168_RSS_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
|
||||
int i;
|
||||
|
||||
/* We require at least one supported parameter to be changed and no
|
||||
* change in any of the unsupported parameters
|
||||
*/
|
||||
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Fill out the redirection table */
|
||||
if (rxfh->indir) {
|
||||
int max_queues = tp->num_rx_rings;
|
||||
|
||||
/* Verify user input. */
|
||||
for (i = 0; i < reta_entries; i++)
|
||||
if (rxfh->indir[i] >= max_queues)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < reta_entries; i++)
|
||||
tp->rss_indir_tbl[i] = rxfh->indir[i];
|
||||
}
|
||||
|
||||
/* Fill out the rss hash key */
|
||||
if (rxfh->key)
|
||||
memcpy(tp->rss_key, rxfh->key, RTL8168_RSS_KEY_SIZE);
|
||||
|
||||
rtl8168_store_reta(tp);
|
||||
|
||||
rtl8168_store_rss_key(tp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int rtl8168_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
|
||||
u8 *hfunc)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
|
||||
if (!(dev->features & NETIF_F_RXHASH))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (hfunc)
|
||||
*hfunc = ETH_RSS_HASH_TOP;
|
||||
|
||||
if (indir)
|
||||
rtl8168_get_reta(tp, indir);
|
||||
|
||||
if (key)
|
||||
memcpy(key, tp->rss_key, RTL8168_RSS_KEY_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8168_set_rxfh(struct net_device *dev, const u32 *indir,
|
||||
const u8 *key, const u8 hfunc)
|
||||
{
|
||||
struct rtl8168_private *tp = netdev_priv(dev);
|
||||
u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
|
||||
int i;
|
||||
|
||||
/* We require at least one supported parameter to be changed and no
|
||||
* change in any of the unsupported parameters
|
||||
*/
|
||||
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Fill out the redirection table */
|
||||
if (indir) {
|
||||
int max_queues = tp->num_rx_rings;
|
||||
|
||||
/* Verify user input. */
|
||||
for (i = 0; i < reta_entries; i++)
|
||||
if (indir[i] >= max_queues)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < reta_entries; i++)
|
||||
tp->rss_indir_tbl[i] = indir[i];
|
||||
}
|
||||
|
||||
/* Fill out the rss hash key */
|
||||
if (key)
|
||||
memcpy(tp->rss_key, key, RTL8168_RSS_KEY_SIZE);
|
||||
|
||||
rtl8168_store_reta(tp);
|
||||
|
||||
rtl8168_store_rss_key(tp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
|
||||
|
||||
static u32 rtl8168_get_rx_desc_hash(struct rtl8168_private *tp,
|
||||
struct RxDescV2 *desc)
|
||||
{
|
||||
if (!desc->RSSResult)
|
||||
fsleep(1);
|
||||
return le32_to_cpu(desc->RSSResult);
|
||||
}
|
||||
|
||||
#define RXS_8168_RSS_IPV4 BIT(17)
|
||||
#define RXS_8168_RSS_IPV6 BIT(18)
|
||||
#define RXS_8168_RSS_TCP BIT(19)
|
||||
#define RTL8168_RXS_RSS_L3_TYPE_MASK (RXS_8168_RSS_IPV4 | RXS_8168_RSS_IPV6)
|
||||
#define RTL8168_RXS_RSS_L4_TYPE_MASK (RXS_8168_RSS_TCP)
|
||||
void rtl8168_rx_hash(struct rtl8168_private *tp,
|
||||
struct RxDescV2 *desc,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
u32 rss_header_info;
|
||||
|
||||
if (!(tp->dev->features & NETIF_F_RXHASH))
|
||||
return;
|
||||
|
||||
rss_header_info = le32_to_cpu(desc->opts2);
|
||||
|
||||
if (!(rss_header_info & RTL8168_RXS_RSS_L3_TYPE_MASK))
|
||||
return;
|
||||
|
||||
skb_set_hash(skb, rtl8168_get_rx_desc_hash(tp, desc),
|
||||
(RTL8168_RXS_RSS_L4_TYPE_MASK & rss_header_info) ?
|
||||
PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
|
||||
}
|
||||
|
||||
void rtl8168_disable_rss(struct rtl8168_private *tp)
|
||||
{
|
||||
rtl8168_eri_write(tp, RSS_CTRL_8168, 4, 0x00000000, ERIAR_ExGMAC);
|
||||
}
|
||||
|
||||
void _rtl8168_config_rss(struct rtl8168_private *tp)
|
||||
{
|
||||
_rtl8168_set_rss_hash_opt(tp);
|
||||
|
||||
rtl8168_store_reta(tp);
|
||||
|
||||
rtl8168_store_rss_key(tp);
|
||||
}
|
||||
|
||||
void rtl8168_config_rss(struct rtl8168_private *tp)
|
||||
{
|
||||
if (!HW_RSS_SUPPORT_RSS(tp))
|
||||
return;
|
||||
|
||||
if (!tp->EnableRss) {
|
||||
rtl8168_disable_rss(tp);
|
||||
return;
|
||||
}
|
||||
|
||||
_rtl8168_config_rss(tp);
|
||||
}
|
||||
|
||||
void rtl8168_init_rss(struct rtl8168_private *tp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rtl8168_rss_indir_tbl_entries(tp); i++)
|
||||
tp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, tp->num_rx_rings);
|
||||
|
||||
netdev_rss_key_fill(tp->rss_key, RTL8168_RSS_KEY_SIZE);
|
||||
}
|
||||
72
drivers/net/ethernet/realtek/r8168/r8168_rss.h
Normal file
72
drivers/net/ethernet/realtek/r8168/r8168_rss.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
################################################################################
|
||||
#
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Author:
|
||||
# Realtek NIC software team <nicfae@realtek.com>
|
||||
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
|
||||
#
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
* This product is covered by one or more of the following patents:
|
||||
* US6,570,884, US6,115,776, and US6,327,625.
|
||||
***********************************************************************************/
|
||||
|
||||
#ifndef _LINUX_RTL8168_RSS_H
|
||||
#define _LINUX_RTL8168_RSS_H
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define RTL8168_RSS_INDIR_TBL_SIZE 8
|
||||
#define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
|
||||
#define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128
|
||||
|
||||
struct rtl8168_private;
|
||||
struct RxDescV2;
|
||||
|
||||
int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
||||
u32 *rule_locs);
|
||||
int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
|
||||
u32 rtl8168_get_rxfh_key_size(struct net_device *netdev);
|
||||
u32 rtl8168_rss_indir_size(struct net_device *netdev);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
|
||||
int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh);
|
||||
int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack);
|
||||
#else
|
||||
int rtl8168_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
|
||||
u8 *hfunc);
|
||||
int rtl8168_set_rxfh(struct net_device *netdev, const u32 *indir,
|
||||
const u8 *key, const u8 hfunc);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
|
||||
void rtl8168_rx_hash(struct rtl8168_private *tp,
|
||||
struct RxDescV2 *desc,
|
||||
struct sk_buff *skb);
|
||||
void _rtl8168_config_rss(struct rtl8168_private *tp);
|
||||
void rtl8168_config_rss(struct rtl8168_private *tp);
|
||||
void rtl8168_init_rss(struct rtl8168_private *tp);
|
||||
u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp);
|
||||
void rtl8168_disable_rss(struct rtl8168_private *tp);
|
||||
|
||||
#endif /* _LINUX_RTL8168_RSS_H */
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
@@ -93,7 +93,7 @@ void rtl8168_eeprom_cleanup(struct rtl8168_private *tp)
|
||||
rtl8168_lower_clock(tp, &x);
|
||||
}
|
||||
|
||||
int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp)
|
||||
static int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp)
|
||||
{
|
||||
u8 x;
|
||||
int i;
|
||||
@@ -104,10 +104,10 @@ int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp)
|
||||
x = RTL_R8(tp, Cfg9346);
|
||||
|
||||
if (x & Cfg9346_EEDO) {
|
||||
udelay(RTL_CLOCK_RATE * 2 * 3);
|
||||
fsleep(RTL_CLOCK_RATE * 2 * 3);
|
||||
return 0;
|
||||
}
|
||||
udelay(1);
|
||||
fsleep(1);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -157,9 +157,8 @@ void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data)
|
||||
int addr_sz = 6;
|
||||
int w_dummy_addr = 4;
|
||||
|
||||
if(tp->eeprom_type == EEPROM_TYPE_NONE) {
|
||||
return ;
|
||||
}
|
||||
if(tp->eeprom_type == EEPROM_TYPE_NONE)
|
||||
return;
|
||||
|
||||
if (tp->eeprom_type==EEPROM_TYPE_93C46) {
|
||||
addr_sz = 6;
|
||||
@@ -178,17 +177,15 @@ void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data)
|
||||
|
||||
rtl8168_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3);
|
||||
rtl8168_shift_out_bits(tp, reg, addr_sz);
|
||||
if (rtl8168_eeprom_cmd_done(tp) < 0) {
|
||||
if (rtl8168_eeprom_cmd_done(tp) < 0)
|
||||
return;
|
||||
}
|
||||
rtl8168_stand_by(tp);
|
||||
|
||||
rtl8168_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3);
|
||||
rtl8168_shift_out_bits(tp, reg, addr_sz);
|
||||
rtl8168_shift_out_bits(tp, data, 16);
|
||||
if (rtl8168_eeprom_cmd_done(tp) < 0) {
|
||||
if (rtl8168_eeprom_cmd_done(tp) < 0)
|
||||
return;
|
||||
}
|
||||
rtl8168_stand_by(tp);
|
||||
|
||||
rtl8168_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5);
|
||||
@@ -202,7 +199,7 @@ void rtl8168_raise_clock(struct rtl8168_private *tp, u8 *x)
|
||||
{
|
||||
*x = *x | Cfg9346_EESK;
|
||||
RTL_W8(tp, Cfg9346, *x);
|
||||
udelay(RTL_CLOCK_RATE);
|
||||
fsleep(RTL_CLOCK_RATE);
|
||||
}
|
||||
|
||||
void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x)
|
||||
@@ -210,7 +207,7 @@ void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x)
|
||||
|
||||
*x = *x & ~Cfg9346_EESK;
|
||||
RTL_W8(tp, Cfg9346, *x);
|
||||
udelay(RTL_CLOCK_RATE);
|
||||
fsleep(RTL_CLOCK_RATE);
|
||||
}
|
||||
|
||||
void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count)
|
||||
@@ -229,7 +226,7 @@ void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count)
|
||||
x &= ~Cfg9346_EEDI;
|
||||
|
||||
RTL_W8(tp, Cfg9346, x);
|
||||
udelay(RTL_CLOCK_RATE);
|
||||
fsleep(RTL_CLOCK_RATE);
|
||||
rtl8168_raise_clock(tp, &x);
|
||||
rtl8168_lower_clock(tp, &x);
|
||||
mask = mask >> 1;
|
||||
@@ -272,7 +269,7 @@ void rtl8168_stand_by(struct rtl8168_private *tp)
|
||||
x = RTL_R8(tp, Cfg9346);
|
||||
x &= ~(Cfg9346_EECS | Cfg9346_EESK);
|
||||
RTL_W8(tp, Cfg9346, x);
|
||||
udelay(RTL_CLOCK_RATE);
|
||||
fsleep(RTL_CLOCK_RATE);
|
||||
|
||||
x |= Cfg9346_EECS;
|
||||
RTL_W8(tp, Cfg9346, x);
|
||||
@@ -283,7 +280,7 @@ void rtl8168_set_eeprom_sel_low(struct rtl8168_private *tp)
|
||||
RTL_W8(tp, Cfg9346, Cfg9346_EEM1);
|
||||
RTL_W8(tp, Cfg9346, Cfg9346_EEM1 | Cfg9346_EESK);
|
||||
|
||||
udelay(20);
|
||||
fsleep(20);
|
||||
|
||||
RTL_W8(tp, Cfg9346, Cfg9346_EEM1);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
@@ -47,7 +47,6 @@
|
||||
int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
{
|
||||
struct rtltool_cmd my_cmd;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd)))
|
||||
@@ -56,6 +55,11 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
ret = 0;
|
||||
switch (my_cmd.cmd) {
|
||||
case RTLTOOL_READ_MAC:
|
||||
if ((my_cmd.offset + my_cmd.len) > R8168_REGS_SIZE) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (my_cmd.len==1)
|
||||
my_cmd.data = readb(tp->mmio_addr+my_cmd.offset);
|
||||
else if (my_cmd.len==2)
|
||||
@@ -72,8 +76,12 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTLTOOL_WRITE_MAC:
|
||||
if ((my_cmd.offset + my_cmd.len) > R8168_REGS_SIZE) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (my_cmd.len==1)
|
||||
writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset);
|
||||
else if (my_cmd.len==2)
|
||||
@@ -84,51 +92,31 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTLTOOL_READ_PHY:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
my_cmd.data = rtl8168_mdio_prot_read(tp, my_cmd.offset);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTLTOOL_WRITE_PHY:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_mdio_prot_write(tp, my_cmd.offset, my_cmd.data);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
break;
|
||||
|
||||
case RTLTOOL_READ_EPHY:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
my_cmd.data = rtl8168_ephy_read(tp, my_cmd.offset);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTLTOOL_WRITE_EPHY:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_ephy_write(tp, my_cmd.offset, my_cmd.data);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
break;
|
||||
|
||||
case RTLTOOL_READ_ERI:
|
||||
my_cmd.data = 0;
|
||||
if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) {
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
my_cmd.data = rtl8168_eri_read(tp, my_cmd.offset, my_cmd.len, ERIAR_ExGMAC);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
} else {
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
@@ -138,20 +126,15 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTLTOOL_WRITE_ERI:
|
||||
if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) {
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_eri_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data, ERIAR_ExGMAC);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
} else {
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTLTOOL_READ_PCI:
|
||||
my_cmd.data = 0;
|
||||
if (my_cmd.len==1)
|
||||
@@ -173,7 +156,6 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTLTOOL_WRITE_PCI:
|
||||
if (my_cmd.len==1)
|
||||
pci_write_config_byte(tp->pci_dev, my_cmd.offset,
|
||||
@@ -188,108 +170,69 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTLTOOL_READ_EEPROM:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
my_cmd.data = rtl8168_eeprom_read_sc(tp, my_cmd.offset);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTLTOOL_WRITE_EEPROM:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_eeprom_write_sc(tp, my_cmd.offset, my_cmd.data);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
break;
|
||||
|
||||
case RTL_READ_OOB_MAC:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_oob_mutex_lock(tp);
|
||||
my_cmd.data = rtl8168_ocp_read(tp, my_cmd.offset, 4);
|
||||
rtl8168_oob_mutex_unlock(tp);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTL_WRITE_OOB_MAC:
|
||||
if (my_cmd.len == 0 || my_cmd.len > 4)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_oob_mutex_lock(tp);
|
||||
rtl8168_ocp_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data);
|
||||
rtl8168_oob_mutex_unlock(tp);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
break;
|
||||
|
||||
case RTL_ENABLE_PCI_DIAG:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
tp->rtk_enable_diag = 1;
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
dprintk("enable rtk diag\n");
|
||||
break;
|
||||
|
||||
case RTL_DISABLE_PCI_DIAG:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
tp->rtk_enable_diag = 0;
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
dprintk("disable rtk diag\n");
|
||||
break;
|
||||
|
||||
case RTL_READ_MAC_OCP:
|
||||
if (my_cmd.offset % 2)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
my_cmd.data = rtl8168_mac_ocp_read(tp, my_cmd.offset);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTL_WRITE_MAC_OCP:
|
||||
if ((my_cmd.offset % 2) || (my_cmd.len != 2))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_mac_ocp_write(tp, my_cmd.offset, (u16)my_cmd.data);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
break;
|
||||
|
||||
case RTL_DIRECT_READ_PHY_OCP:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
my_cmd.data = rtl8168_mdio_prot_direct_read_phy_ocp(tp, my_cmd.offset);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
|
||||
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RTL_DIRECT_WRITE_PHY_OCP:
|
||||
spin_lock_irqsave(&tp->lock, flags);
|
||||
rtl8168_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data);
|
||||
spin_unlock_irqrestore(&tp->lock, flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||
# controllers with PCI-Express interface.
|
||||
#
|
||||
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
|
||||
# Copyright(c) 2024 Realtek Semiconductor Corp. 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
|
||||
|
||||
@@ -174,25 +174,29 @@ static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv)
|
||||
|
||||
static int rockchip_p3phy_rk3588_calibrate(struct rockchip_p3phy_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 reg;
|
||||
u32 phy0_status, phy1_status;
|
||||
int i, sleep_us = 100;
|
||||
bool check_both = (priv->pcie30_phymode == PHY_MODE_PCIE_AGGREGATION);
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->phy_grf,
|
||||
RK3588_PCIE3PHY_GRF_PHY0_STATUS1,
|
||||
reg, RK3588_SRAM_INIT_DONE(reg),
|
||||
100, RK_PCIE_SRAM_INIT_TIMEOUT);
|
||||
if (priv->pcie30_phymode == PHY_MODE_PCIE_AGGREGATION) {
|
||||
ret |= regmap_read_poll_timeout(priv->phy_grf,
|
||||
RK3588_PCIE3PHY_GRF_PHY1_STATUS1,
|
||||
reg, RK3588_SRAM_INIT_DONE(reg),
|
||||
100, RK_PCIE_SRAM_INIT_TIMEOUT);
|
||||
for (i = 0; i < RK_PCIE_SRAM_INIT_TIMEOUT; i += sleep_us) {
|
||||
regmap_read(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_STATUS1, &phy0_status);
|
||||
regmap_read(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_STATUS1, &phy1_status);
|
||||
|
||||
if (check_both) {
|
||||
if (RK3588_SRAM_INIT_DONE(phy0_status) && RK3588_SRAM_INIT_DONE(phy1_status))
|
||||
return 0;
|
||||
} else {
|
||||
if (RK3588_SRAM_INIT_DONE(phy0_status) || RK3588_SRAM_INIT_DONE(phy1_status))
|
||||
return 0;
|
||||
}
|
||||
|
||||
usleep_range(sleep_us, sleep_us + 10);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(&priv->phy->dev, "%s: lock failed 0x%x, check input refclk and power supply\n",
|
||||
__func__, reg);
|
||||
pr_err("%s: lock failed p0=0x%x p1=0x%x, check input refclk and power supply\n",
|
||||
__func__, phy0_status, phy1_status);
|
||||
|
||||
return ret;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static const struct rockchip_p3phy_ops rk3588_ops = {
|
||||
|
||||
@@ -537,7 +537,7 @@ static int rkvdec2_link_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task)
|
||||
struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
|
||||
struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
|
||||
struct rkvdec_link_dev *link_dec = dec->link_dec;
|
||||
struct mpp_dma_buffer *table = link_dec->table;
|
||||
struct mpp_dma_buffer *table = task->table;
|
||||
struct rkvdec_link_info *info = link_dec->info;
|
||||
struct rkvdec_link_part *part = info->part_r;
|
||||
u32 *tb_reg = (u32 *)table->vaddr;
|
||||
|
||||
@@ -83,4 +83,6 @@ void rga_dump_memory_parm(struct rga_memory_parm *parm);
|
||||
void rga_dump_external_buffer(struct rga_external_buffer *buffer);
|
||||
void rga_dump_req(struct rga_request *request, struct rga_req *req);
|
||||
|
||||
unsigned long rga_get_free_pages(gfp_t gfp_mask, unsigned int *order, unsigned long size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -925,3 +925,27 @@ void rga_dump_req(struct rga_request *request, struct rga_req *req)
|
||||
rga_req_log(request, "core_mask = %#x, priority = %d, in_fence = %d(%#x)\n",
|
||||
req->core, req->priority, req->in_fence_fd, req->in_fence_fd);
|
||||
}
|
||||
|
||||
unsigned long rga_get_free_pages(gfp_t gfp_mask, unsigned int *order, unsigned long size)
|
||||
{
|
||||
int cur_order, max_order;
|
||||
unsigned long pages;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0)
|
||||
max_order = MAX_ORDER;
|
||||
#else
|
||||
max_order = MAX_PAGE_ORDER;
|
||||
#endif
|
||||
|
||||
cur_order = get_order(size);
|
||||
if (cur_order > max_order) {
|
||||
rga_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n",
|
||||
cur_order, max_order);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pages = __get_free_pages(gfp_mask, cur_order);
|
||||
*order = cur_order;
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "rga.h"
|
||||
#include "rga_debugger.h"
|
||||
|
||||
@@ -1497,7 +1497,11 @@ pm_disable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0)
|
||||
static int rga_drv_remove(struct platform_device *pdev)
|
||||
#else
|
||||
static void rga_drv_remove(struct platform_device *pdev)
|
||||
#endif
|
||||
{
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
@@ -1515,7 +1519,9 @@ static int rga_drv_remove(struct platform_device *pdev)
|
||||
|
||||
up_write(&rga_drvdata->rwsem);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rga_drv_shutdown(struct platform_device *pdev)
|
||||
|
||||
@@ -167,28 +167,16 @@ struct rga_mmu_base *rga_mmu_base_init(size_t size)
|
||||
* malloc pre scale mid buf mmu table:
|
||||
* size * channel_num * address_size
|
||||
*/
|
||||
order = get_order(size * 3 * sizeof(*mmu_base->buf_virtual));
|
||||
if (order >= MAX_ORDER) {
|
||||
pr_err("Can not alloc pages with order[%d] for mmu_page_table, max_order = %d\n",
|
||||
order, MAX_ORDER);
|
||||
goto err_free_mmu_base;
|
||||
}
|
||||
|
||||
mmu_base->buf_virtual = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order);
|
||||
mmu_base->buf_virtual = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32,
|
||||
&order, size * 3 * sizeof(*mmu_base->buf_virtual));
|
||||
if (mmu_base->buf_virtual == NULL) {
|
||||
pr_err("Can not alloc pages for mmu_page_table\n");
|
||||
goto err_free_mmu_base;
|
||||
}
|
||||
mmu_base->buf_order = order;
|
||||
|
||||
order = get_order(size * sizeof(*mmu_base->pages));
|
||||
if (order >= MAX_ORDER) {
|
||||
pr_err("Can not alloc pages with order[%d] for mmu_base->pages, max_order = %d\n",
|
||||
order, MAX_ORDER);
|
||||
goto err_free_buf_virtual;
|
||||
}
|
||||
|
||||
mmu_base->pages = (struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
|
||||
mmu_base->pages = (struct page **)rga_get_free_pages(GFP_KERNEL | GFP_DMA32,
|
||||
&order, size * sizeof(*mmu_base->pages));
|
||||
if (mmu_base->pages == NULL) {
|
||||
pr_err("Can not alloc pages for mmu_base->pages\n");
|
||||
goto err_free_buf_virtual;
|
||||
|
||||
@@ -133,9 +133,12 @@ static int rga_get_user_pages(struct page **pages, unsigned long Memory,
|
||||
result = get_user_pages_remote(current, current_mm,
|
||||
Memory << PAGE_SHIFT,
|
||||
pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL);
|
||||
#else
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0)
|
||||
result = get_user_pages_remote(current_mm, Memory << PAGE_SHIFT,
|
||||
pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL);
|
||||
#else
|
||||
result = get_user_pages_remote(current_mm, Memory << PAGE_SHIFT,
|
||||
pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL);
|
||||
#endif
|
||||
|
||||
if (result > 0 && result >= pageCount) {
|
||||
@@ -252,14 +255,8 @@ static int rga_alloc_virt_addr(struct rga_virt_addr **virt_addr_p,
|
||||
}
|
||||
|
||||
/* alloc pages and page_table */
|
||||
order = get_order(count * sizeof(struct page *));
|
||||
if (order >= MAX_ORDER) {
|
||||
rga_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n",
|
||||
order, MAX_ORDER);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pages = (struct page **)__get_free_pages(GFP_KERNEL, order);
|
||||
pages = (struct page **)rga_get_free_pages(GFP_KERNEL,
|
||||
&order, count * sizeof(struct page *));
|
||||
if (pages == NULL) {
|
||||
rga_err("%s can not alloc pages for viraddr pages\n", __func__);
|
||||
return -ENOMEM;
|
||||
@@ -1196,14 +1193,8 @@ static int rga_mm_set_mmu_base(struct rga_job *job,
|
||||
}
|
||||
|
||||
if (job->flags & RGA_JOB_USE_HANDLE) {
|
||||
order = get_order(page_count * sizeof(uint32_t *));
|
||||
if (order >= MAX_ORDER) {
|
||||
rga_job_err(job, "Can not alloc pages with order[%d] for page_table, max_order = %d\n",
|
||||
order, MAX_ORDER);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
|
||||
page_table = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32,
|
||||
&order, page_count * sizeof(uint32_t *));
|
||||
if (page_table == NULL) {
|
||||
rga_job_err(job, "%s can not alloc pages for page_table, order = %d\n",
|
||||
__func__, order);
|
||||
@@ -1261,14 +1252,8 @@ static int rga_mm_set_mmu_base(struct rga_job *job,
|
||||
}
|
||||
|
||||
if (job->flags & RGA_JOB_USE_HANDLE) {
|
||||
order = get_order(page_count * sizeof(uint32_t *));
|
||||
if (order >= MAX_ORDER) {
|
||||
rga_job_err(job, "Can not alloc pages with order[%d] for page_table, max_order = %d\n",
|
||||
order, MAX_ORDER);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
|
||||
page_table = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32,
|
||||
&order, page_count * sizeof(uint32_t *));
|
||||
if (page_table == NULL) {
|
||||
rga_job_err(job, "%s can not alloc pages for page_table, order = %d\n",
|
||||
__func__, order);
|
||||
|
||||
Reference in New Issue
Block a user