xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/rga3/rga_policy.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) Rockchip Electronics Co., Ltd.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Author: Huang Lee <Putin.li@rock-chips.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define pr_fmt(fmt) "rga_policy: " fmt
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "rga_job.h"
11*4882a593Smuzhiyun #include "rga_common.h"
12*4882a593Smuzhiyun #include "rga_hw_config.h"
13*4882a593Smuzhiyun #include "rga_debugger.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #define GET_GCD(n1, n2) \
16*4882a593Smuzhiyun 	({ \
17*4882a593Smuzhiyun 		int i; \
18*4882a593Smuzhiyun 		int gcd = 0; \
19*4882a593Smuzhiyun 		for (i = 1; i <= (n1) && i <= (n2); i++) { \
20*4882a593Smuzhiyun 			if ((n1) % i == 0 && (n2) % i == 0) \
21*4882a593Smuzhiyun 				gcd = i; \
22*4882a593Smuzhiyun 		} \
23*4882a593Smuzhiyun 		gcd; \
24*4882a593Smuzhiyun 	})
25*4882a593Smuzhiyun #define GET_LCM(n1, n2, gcd) (((n1) * (n2)) / gcd)
26*4882a593Smuzhiyun 
rga_set_feature(struct rga_req * rga_base)27*4882a593Smuzhiyun static int rga_set_feature(struct rga_req *rga_base)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	int feature = 0;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	if (rga_base->render_mode == COLOR_FILL_MODE)
32*4882a593Smuzhiyun 		feature |= RGA_COLOR_FILL;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	if (rga_base->render_mode == COLOR_PALETTE_MODE)
35*4882a593Smuzhiyun 		feature |= RGA_COLOR_PALETTE;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	if (rga_base->color_key_max > 0 || rga_base->color_key_min > 0)
38*4882a593Smuzhiyun 		feature |= RGA_COLOR_KEY;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	if ((rga_base->alpha_rop_flag >> 1) & 1)
41*4882a593Smuzhiyun 		feature |= RGA_ROP_CALCULATE;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	if ((rga_base->alpha_rop_flag >> 8) & 1)
44*4882a593Smuzhiyun 		feature |= RGA_NN_QUANTIZE;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	return feature;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
rga_check_resolution(const struct rga_rect_range * range,int width,int height)49*4882a593Smuzhiyun static bool rga_check_resolution(const struct rga_rect_range *range, int width, int height)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	if (width > range->max.width || height > range->max.height)
52*4882a593Smuzhiyun 		return false;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	if (width < range->min.width || height < range->min.height)
55*4882a593Smuzhiyun 		return false;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	return true;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
rga_check_format(const struct rga_hw_data * data,int rd_mode,int format,int win_num)60*4882a593Smuzhiyun static bool rga_check_format(const struct rga_hw_data *data,
61*4882a593Smuzhiyun 		int rd_mode, int format, int win_num)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	int i;
64*4882a593Smuzhiyun 	bool matched = false;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	if (rd_mode == RGA_RASTER_MODE) {
67*4882a593Smuzhiyun 		for (i = 0; i < data->win[win_num].num_of_raster_formats; i++) {
68*4882a593Smuzhiyun 			if (format == data->win[win_num].raster_formats[i]) {
69*4882a593Smuzhiyun 				matched = true;
70*4882a593Smuzhiyun 				break;
71*4882a593Smuzhiyun 			}
72*4882a593Smuzhiyun 		}
73*4882a593Smuzhiyun 	} else if (rd_mode == RGA_FBC_MODE) {
74*4882a593Smuzhiyun 		for (i = 0; i < data->win[win_num].num_of_fbc_formats; i++) {
75*4882a593Smuzhiyun 			if (format == data->win[win_num].fbc_formats[i]) {
76*4882a593Smuzhiyun 				matched = true;
77*4882a593Smuzhiyun 				break;
78*4882a593Smuzhiyun 			}
79*4882a593Smuzhiyun 		}
80*4882a593Smuzhiyun 	} else if (rd_mode == RGA_TILE_MODE) {
81*4882a593Smuzhiyun 		for (i = 0; i < data->win[win_num].num_of_tile_formats; i++) {
82*4882a593Smuzhiyun 			if (format == data->win[win_num].tile_formats[i]) {
83*4882a593Smuzhiyun 				matched = true;
84*4882a593Smuzhiyun 				break;
85*4882a593Smuzhiyun 			}
86*4882a593Smuzhiyun 		}
87*4882a593Smuzhiyun 	}
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	return matched;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
rga_check_align(uint32_t byte_stride_align,uint32_t format,uint16_t w_stride)92*4882a593Smuzhiyun static bool rga_check_align(uint32_t byte_stride_align, uint32_t format, uint16_t w_stride)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	int bit_stride, pixel_stride, align, gcd;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	pixel_stride = rga_get_pixel_stride_from_format(format);
97*4882a593Smuzhiyun 	if (pixel_stride <= 0)
98*4882a593Smuzhiyun 		return false;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	bit_stride = pixel_stride * w_stride;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	if (bit_stride % (byte_stride_align * 8) == 0)
103*4882a593Smuzhiyun 		return true;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	if (DEBUGGER_EN(MSG)) {
106*4882a593Smuzhiyun 		gcd = GET_GCD(pixel_stride, byte_stride_align * 8);
107*4882a593Smuzhiyun 		align = GET_LCM(pixel_stride, byte_stride_align * 8, gcd) / pixel_stride;
108*4882a593Smuzhiyun 		pr_info("unsupported width stride %d, 0x%x should be %d aligned!",
109*4882a593Smuzhiyun 			w_stride, format, align);
110*4882a593Smuzhiyun 	}
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	return false;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
rga_check_src0(const struct rga_hw_data * data,struct rga_img_info_t * src0)115*4882a593Smuzhiyun static bool rga_check_src0(const struct rga_hw_data *data,
116*4882a593Smuzhiyun 			 struct rga_img_info_t *src0)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	if (!rga_check_resolution(&data->input_range, src0->act_w, src0->act_h))
119*4882a593Smuzhiyun 		return false;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	if (data == &rga3_data &&
122*4882a593Smuzhiyun 	    !rga_check_resolution(&data->input_range,
123*4882a593Smuzhiyun 				  src0->act_w + src0->x_offset,
124*4882a593Smuzhiyun 				  src0->act_h + src0->y_offset))
125*4882a593Smuzhiyun 		return false;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	if (!rga_check_format(data, src0->rd_mode, src0->format, 0))
128*4882a593Smuzhiyun 		return false;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	if (!rga_check_align(data->byte_stride_align, src0->format, src0->vir_w))
131*4882a593Smuzhiyun 		return false;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	return true;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun 
rga_check_src1(const struct rga_hw_data * data,struct rga_img_info_t * src1)136*4882a593Smuzhiyun static bool rga_check_src1(const struct rga_hw_data *data,
137*4882a593Smuzhiyun 			 struct rga_img_info_t *src1)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	if (!rga_check_resolution(&data->input_range, src1->act_w, src1->act_h))
140*4882a593Smuzhiyun 		return false;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	if (data == &rga3_data &&
143*4882a593Smuzhiyun 	    !rga_check_resolution(&data->input_range,
144*4882a593Smuzhiyun 				  src1->act_w + src1->x_offset,
145*4882a593Smuzhiyun 				  src1->act_h + src1->y_offset))
146*4882a593Smuzhiyun 		return false;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	if (!rga_check_format(data, src1->rd_mode, src1->format, 1))
149*4882a593Smuzhiyun 		return false;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	if (!rga_check_align(data->byte_stride_align, src1->format, src1->vir_w))
152*4882a593Smuzhiyun 		return false;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	return true;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
rga_check_dst(const struct rga_hw_data * data,struct rga_img_info_t * dst)157*4882a593Smuzhiyun static bool rga_check_dst(const struct rga_hw_data *data,
158*4882a593Smuzhiyun 			 struct rga_img_info_t *dst)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	if (!rga_check_resolution(&data->output_range, dst->act_w, dst->act_h))
161*4882a593Smuzhiyun 		return false;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	if (data == &rga3_data &&
164*4882a593Smuzhiyun 	    !rga_check_resolution(&data->output_range,
165*4882a593Smuzhiyun 				  dst->act_w + dst->x_offset,
166*4882a593Smuzhiyun 				  dst->act_h + dst->y_offset))
167*4882a593Smuzhiyun 		return false;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	if (!rga_check_format(data, dst->rd_mode, dst->format, 2))
170*4882a593Smuzhiyun 		return false;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	if (!rga_check_align(data->byte_stride_align, dst->format, dst->vir_w))
173*4882a593Smuzhiyun 		return false;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	return true;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
rga_check_scale(const struct rga_hw_data * data,struct rga_req * rga_base)178*4882a593Smuzhiyun static bool rga_check_scale(const struct rga_hw_data *data,
179*4882a593Smuzhiyun 				struct rga_req *rga_base)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	struct rga_img_info_t *src0 = &rga_base->src;
182*4882a593Smuzhiyun 	struct rga_img_info_t *dst = &rga_base->dst;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	int sw, sh;
185*4882a593Smuzhiyun 	int dw, dh;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	sw = src0->act_w;
188*4882a593Smuzhiyun 	sh = src0->act_h;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	if ((rga_base->sina == 65536 && rga_base->cosa == 0)
191*4882a593Smuzhiyun 		|| (rga_base->sina == -65536 && rga_base->cosa == 0)) {
192*4882a593Smuzhiyun 		dw = dst->act_h;
193*4882a593Smuzhiyun 		dh = dst->act_w;
194*4882a593Smuzhiyun 	} else {
195*4882a593Smuzhiyun 		dw = dst->act_w;
196*4882a593Smuzhiyun 		dh = dst->act_h;
197*4882a593Smuzhiyun 	}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	if (sw > dw) {
200*4882a593Smuzhiyun 		if ((sw >> data->max_downscale_factor) > dw)
201*4882a593Smuzhiyun 			return false;
202*4882a593Smuzhiyun 	} else if (sw < dw) {
203*4882a593Smuzhiyun 		if ((sw << data->max_upscale_factor) < dw)
204*4882a593Smuzhiyun 			return false;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	if (sh > dh) {
208*4882a593Smuzhiyun 		if ((sh >> data->max_downscale_factor) > dh)
209*4882a593Smuzhiyun 			return false;
210*4882a593Smuzhiyun 	} else if (sh < dh) {
211*4882a593Smuzhiyun 		if ((sh << data->max_upscale_factor) < dh)
212*4882a593Smuzhiyun 			return false;
213*4882a593Smuzhiyun 	}
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	return true;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
rga_job_assign(struct rga_job * job)218*4882a593Smuzhiyun int rga_job_assign(struct rga_job *job)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	struct rga_img_info_t *src0 = &job->rga_command_base.src;
221*4882a593Smuzhiyun 	struct rga_img_info_t *src1 = &job->rga_command_base.pat;
222*4882a593Smuzhiyun 	struct rga_img_info_t *dst = &job->rga_command_base.dst;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	struct rga_req *rga_base = &job->rga_command_base;
225*4882a593Smuzhiyun 	const struct rga_hw_data *data;
226*4882a593Smuzhiyun 	struct rga_scheduler_t *scheduler = NULL;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	int feature;
229*4882a593Smuzhiyun 	int core = RGA_NONE_CORE;
230*4882a593Smuzhiyun 	int optional_cores = RGA_NONE_CORE;
231*4882a593Smuzhiyun 	int specified_cores = RGA_NONE_CORE;
232*4882a593Smuzhiyun 	int i;
233*4882a593Smuzhiyun 	int min_of_job_count = -1;
234*4882a593Smuzhiyun 	unsigned long flags;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	/* assigned by userspace */
237*4882a593Smuzhiyun 	if (rga_base->core > RGA_NONE_CORE) {
238*4882a593Smuzhiyun 		if (rga_base->core > RGA_CORE_MASK) {
239*4882a593Smuzhiyun 			pr_err("invalid setting core by user\n");
240*4882a593Smuzhiyun 			goto finish;
241*4882a593Smuzhiyun 		} else if (rga_base->core & RGA_CORE_MASK)
242*4882a593Smuzhiyun 			specified_cores = rga_base->core;
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	feature = rga_set_feature(rga_base);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	/* function */
248*4882a593Smuzhiyun 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
249*4882a593Smuzhiyun 		data = rga_drvdata->scheduler[i]->data;
250*4882a593Smuzhiyun 		scheduler = rga_drvdata->scheduler[i];
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 		if ((specified_cores != RGA_NONE_CORE) &&
253*4882a593Smuzhiyun 			(!(scheduler->core & specified_cores)))
254*4882a593Smuzhiyun 			continue;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 		if (DEBUGGER_EN(MSG))
257*4882a593Smuzhiyun 			pr_info("start policy on core = %d", scheduler->core);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 		if (scheduler->data->mmu == RGA_MMU &&
260*4882a593Smuzhiyun 		    job->flags & RGA_JOB_UNSUPPORT_RGA_MMU) {
261*4882a593Smuzhiyun 			if (DEBUGGER_EN(MSG))
262*4882a593Smuzhiyun 				pr_info("RGA2 only support under 4G memory!\n");
263*4882a593Smuzhiyun 			continue;
264*4882a593Smuzhiyun 		}
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 		if (feature > 0) {
267*4882a593Smuzhiyun 			if (!(feature & data->feature)) {
268*4882a593Smuzhiyun 				if (DEBUGGER_EN(MSG))
269*4882a593Smuzhiyun 					pr_info("core = %d, break on feature",
270*4882a593Smuzhiyun 						scheduler->core);
271*4882a593Smuzhiyun 				continue;
272*4882a593Smuzhiyun 			}
273*4882a593Smuzhiyun 		}
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 		/* only colorfill need single win (colorpalette?) */
276*4882a593Smuzhiyun 		if (!(feature & 1)) {
277*4882a593Smuzhiyun 			if (src1->yrgb_addr > 0) {
278*4882a593Smuzhiyun 				if ((!(src0->rd_mode & data->win[0].rd_mode)) ||
279*4882a593Smuzhiyun 					(!(src1->rd_mode & data->win[1].rd_mode)) ||
280*4882a593Smuzhiyun 					(!(dst->rd_mode & data->win[2].rd_mode))) {
281*4882a593Smuzhiyun 					if (DEBUGGER_EN(MSG))
282*4882a593Smuzhiyun 						pr_info("core = %d, ABC break on rd_mode",
283*4882a593Smuzhiyun 							scheduler->core);
284*4882a593Smuzhiyun 					continue;
285*4882a593Smuzhiyun 				}
286*4882a593Smuzhiyun 			} else {
287*4882a593Smuzhiyun 				if ((!(src0->rd_mode & data->win[0].rd_mode)) ||
288*4882a593Smuzhiyun 					(!(dst->rd_mode & data->win[2].rd_mode))) {
289*4882a593Smuzhiyun 					if (DEBUGGER_EN(MSG))
290*4882a593Smuzhiyun 						pr_info("core = %d, ABB break on rd_mode",
291*4882a593Smuzhiyun 							scheduler->core);
292*4882a593Smuzhiyun 					continue;
293*4882a593Smuzhiyun 				}
294*4882a593Smuzhiyun 			}
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 			if (!rga_check_scale(data, rga_base)) {
297*4882a593Smuzhiyun 				if (DEBUGGER_EN(MSG))
298*4882a593Smuzhiyun 					pr_info("core = %d, break on rga_check_scale",
299*4882a593Smuzhiyun 						scheduler->core);
300*4882a593Smuzhiyun 				continue;
301*4882a593Smuzhiyun 			}
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 			if (!rga_check_src0(data, src0)) {
304*4882a593Smuzhiyun 				if (DEBUGGER_EN(MSG))
305*4882a593Smuzhiyun 					pr_info("core = %d, break on rga_check_src0",
306*4882a593Smuzhiyun 						scheduler->core);
307*4882a593Smuzhiyun 				continue;
308*4882a593Smuzhiyun 			}
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 			if (src1->yrgb_addr > 0) {
311*4882a593Smuzhiyun 				if (!rga_check_src1(data, src1)) {
312*4882a593Smuzhiyun 					if (DEBUGGER_EN(MSG))
313*4882a593Smuzhiyun 						pr_info("core = %d, break on rga_check_src1",
314*4882a593Smuzhiyun 							scheduler->core);
315*4882a593Smuzhiyun 					continue;
316*4882a593Smuzhiyun 				}
317*4882a593Smuzhiyun 			}
318*4882a593Smuzhiyun 		}
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 		if (!rga_check_dst(data, dst)) {
321*4882a593Smuzhiyun 			if (DEBUGGER_EN(MSG))
322*4882a593Smuzhiyun 				pr_info("core = %d, break on rga_check_dst",
323*4882a593Smuzhiyun 					scheduler->core);
324*4882a593Smuzhiyun 			continue;
325*4882a593Smuzhiyun 		}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 		optional_cores |= scheduler->core;
328*4882a593Smuzhiyun 	}
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	if (DEBUGGER_EN(MSG))
331*4882a593Smuzhiyun 		pr_info("optional_cores = %d\n", optional_cores);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	if (optional_cores == 0) {
334*4882a593Smuzhiyun 		core = -1;
335*4882a593Smuzhiyun 		pr_err("invalid function policy\n");
336*4882a593Smuzhiyun 		goto finish;
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
340*4882a593Smuzhiyun 		scheduler = rga_drvdata->scheduler[i];
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 		if (optional_cores & scheduler->core) {
343*4882a593Smuzhiyun 			spin_lock_irqsave(&scheduler->irq_lock, flags);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 			if (scheduler->running_job == NULL) {
346*4882a593Smuzhiyun 				core = scheduler->core;
347*4882a593Smuzhiyun 				job->scheduler = scheduler;
348*4882a593Smuzhiyun 				spin_unlock_irqrestore(&scheduler->irq_lock,
349*4882a593Smuzhiyun 							 flags);
350*4882a593Smuzhiyun 				break;
351*4882a593Smuzhiyun 			} else {
352*4882a593Smuzhiyun 				if ((min_of_job_count == -1) ||
353*4882a593Smuzhiyun 				    (min_of_job_count > scheduler->job_count)) {
354*4882a593Smuzhiyun 					min_of_job_count = scheduler->job_count;
355*4882a593Smuzhiyun 					core = scheduler->core;
356*4882a593Smuzhiyun 					job->scheduler = scheduler;
357*4882a593Smuzhiyun 				}
358*4882a593Smuzhiyun 			}
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 			spin_unlock_irqrestore(&scheduler->irq_lock, flags);
361*4882a593Smuzhiyun 		}
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	/* TODO: need consider full load */
365*4882a593Smuzhiyun finish:
366*4882a593Smuzhiyun 	if (DEBUGGER_EN(MSG))
367*4882a593Smuzhiyun 		pr_info("assign core: %d\n", core);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	return core;
370*4882a593Smuzhiyun }
371